Favicon in Datei speichern



  • Ich möchte das Icon von einer Website in einer Datei speichern. Dafür habe ich ein boost asio Beispiel benutzt, leider ist die Datei unlesbar. Mache ich schon etwas beim herunterladen falsch oder liegt es an ofstream?

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <boost/asio.hpp>
    #include <boost/array.hpp>
    
    using namespace std;
    
    bool getFaviconFromWebsite( const std::string& address, const std::string& filePath )
    {
        boost::asio::io_service io_service;
    
        boost::asio::ip::tcp::resolver resolver(io_service);
        boost::asio::ip::tcp::resolver::query query( address, "http");
        boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    
        boost::asio::ip::tcp::socket socket(io_service);
        boost::asio::connect(socket, endpoint_iterator);
    
        boost::asio::streambuf request;
        std::ostream request_stream( &request );
        request_stream << "GET /favicon.ico HTTP/1.0\r\n";
        request_stream << "Host: " << address << "\r\n";
        request_stream << "Accept: */*\r\n";
        request_stream << "Connection: close\r\n\r\n";
    
        boost::asio::write(socket, request);
    
        boost::asio::streambuf response;
        boost::asio::read_until(socket, response, "\r\n");
    
        std::istream response_stream(&response);
        std::string http_version;
        response_stream >> http_version;
        unsigned int status_code;
        response_stream >> status_code;
        std::string status_message;
        std::getline(response_stream, status_message);
        if (!response_stream || http_version.substr(0, 5) != "HTTP/")
        {
            std::cout << "HTTP\n";
            return false;
        }
        if (status_code != 200)
        {
            std::cout << status_code;
            return false;
        }
    
        boost::asio::read_until(socket, response, "\r\n\r\n");
        size_t size = response.size();
        response.consume(size);
    
        boost::asio::streambuf buffer;
    
        std::ofstream file( filePath );
    
        if(!file)
        {
            std::cout << "!file\n";
            return false;
        }
        boost::system::error_code error;
        while (boost::asio::read(socket, buffer,
               boost::asio::transfer_at_least(1), error))
        {
            file << &buffer;
        }
        if (error != boost::asio::error::eof)
        {
            std::cout << "!read\n";
            return false;
        }
        return true;
    }
    
    int main() try
    {
        if(! getFaviconFromWebsite( "www.google.de", "google.ico" ) )
            std::cout << "error";
        else
            std::cout << "true";
    }
    catch ( const boost::system::system_error &e )
    {
        boost::system::error_code ec = e.code();
        std::cerr << ec.value() << std::endl;
        std::cerr << ec.category().name() << std::endl;
    }
    


  • Naja, du schreibst die Adresse des Buffers in die Datei, oder?

    file << &buffer;
    


  • manni66 schrieb:

    Naja, du schreibst die Adresse des Buffers in die Datei, oder?

    file << &buffer;
    

    Danke, habe es jetzt vebessert, aber leider ist die Datei immer noch nicht lesbar.

    file << boost::asio::buffer_cast<const char*>( buffer.data() );
    


  • unwissendernarr schrieb:

    Danke, habe es jetzt vebessert, aber leider ist die Datei immer noch nicht lesbar.

    file << boost::asio::buffer_cast<const char*>( buffer.data() );
    

    1. schreibt das nur bis zum ersten '\0', was aber in einer Binärdatei durchaus vorkommen kann
    2. muss in den Daten kein '\0' vorkommen, d.h. du schreibst möglicherweise mehr als der Buffer lang ist
    3. du darfst nur genau so viele Daten aus dem Buffer schreiben, wie die Leseoperation auch reingeschrieben hat



  • Du solltest Bilder immer als Binärdatei abspeichern:

    std::ofstream file( filePath, ios::binary );
    

Anmelden zum Antworten