Получить файл из Интернета с помощью GLib / GIO из C

С помощью какой функции мне следует получить файл из Интернета с помощью библиотек GLib / GIO?

Если мой файл из:

gchar *path = "http://xxx.yyyServer/sharing/temp.txt"

Что мне делать, чтобы его скачать?

Для локальных файлов я просто использую библиотеки C, такие как fopen и fread.

Как мне сделать это?

К сожалению, в обучающих материалах нет примеров работы с файлами. Я могу видеть только средство выбора файла в диалоговых окнах "Файл".


ОБНОВЛЕНО РАБОЧИМ КОДОМ ИЗ КОММЕНТАРИЙ: приведенный ниже код работает с двоичными файлами неизвестного размера.

char *name= http://127.0.0.1:8000/mybinfile


int getFile(char *name)
{

    GFile *f = g_file_new_for_uri(name);
    GFileInputStream *fis = NULL;
    GDataInputStream* dis = NULL;
    GError *err = NULL;
    //char buffer[2048];
    char *buffer;
    size_t length;
    int ret = -1;

    GFileInfo *info;

    int total_size = -1;

    /* get input stream */
    fis = g_file_read(f, NULL, &err);

    if (err != NULL) {
        fprintf(stderr, "ERROR: opening %s\n", name);
        g_object_unref(f);
        return -1;
    }

    info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (fis),G_FILE_ATTRIBUTE_STANDARD_SIZE,NULL, &err);
    if (info)
    {
        if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE))
            total_size = g_file_info_get_size (info);
            printf( "total_size = %d\n", total_size);
            g_object_unref (info);
    }

    // fill buffer
    if(total_size > 0){
        buffer = (char *) malloc(sizeof(char) * total_size);
        memset(buffer, 0, total_size);
        if ((length = g_input_stream_read (G_INPUT_STREAM(fis),
                    buffer, total_size, NULL, &err)) != -1) {
                printf( "reading file\n");
        }
        printf( "File length = %d\n", length);

            ret = 0;
        }
        // close streams
        g_object_unref(fis);
        g_object_unref(f);   
        return ret;
    }

person user907810    schedule 16.05.2012    source источник
comment
Как насчет грязного взлома? int meh = system (wget + имя);   -  person Mikhail    schedule 16.05.2012


Ответы (2)


HTTP - это один из протоколов, поддерживаемых GIO, поэтому вы можете открыть HTTP-URI, как и любой другой файл, при использовании функций GIO вместо стандартных функций C. Просто используйте g_file_new_for_uri для создания файлового объекта, а затем вы можете прочтите его как локальный файл.

Вы можете использовать g_file_read, чтобы получить GFileInputStream для данного URI, а затем g_data_input_stream_new, чтобы получить GDataInputStream для входного потока, который затем можно использовать для построчного чтения файла. Вы должны преобразовать GFileInputStream в GInputStream, прежде чем вы сможете передать его g_data_input_stream_new (или прежде, чем вы сможете сделать с ним что-нибудь полезное), но если вы программируете GTK на C, вы, вероятно, уже привыкли к этому.

person sepp2k    schedule 16.05.2012
comment
Спасибо sepp2k. Я собираюсь попробовать, и как только код заработает, опубликую его для потомков;) - person user907810; 21.05.2012
comment
Как мне заранее узнать размер файла, прежде чем выделить подходящий буфер для его чтения? В C я бы сделал это с помощью fseek и ftell. Возможно ли это в GTK? - person user907810; 21.05.2012
comment
@ user907810 Вы можете получить объект GFileInfo из файлового объекта, а затем вызвать для него g_file_info_get_size. - person sepp2k; 21.05.2012

Я новичок, как и вы с GTK (может быть, даже больше), но подозреваю, что не существует способа загрузки файла с одной инструкцией на C / C ++. Вы должны использовать внешние инструменты (wget и т. Д.) Или написать процедуру GET самостоятельно. Здесь приведен пример загрузки файла на C с использованием libcurl. Удачи!

person Avio    schedule 16.05.2012
comment
Честно говоря, из документации gtk я не видел примеров обработки файлов, кроме диалога выбора файлов, и поэтому даже для чтения локальных файлов я просто закодировал fread в стиле C ... - person user907810; 21.05.2012
comment
Единственная проблема с использованием libcurl в том, что мне также нужно установить библиотеку libcurl. На самом деле я программирую для встроенного приложения ARM, и если эта библиотека по умолчанию недоступна, мне придется ее кросс-компилировать .. - person user907810; 21.05.2012