Fetch a file from web using GLib/GIO from C
Asked Answered
I

2

8

With what function should I fetch a file from the web using GLib/GIO libs?

If my file is from:

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

What should I do to download it?

For the local files I simply use C libraries like fopen and fread.

How should I do the above?

There is unfortunately no examples of file handling in the Tutorials. I can only see a File chooser from File Dialog boxes.


UPDATED WITH WORKING CODE FROM COMMENTS: The code below works for binary files of unknown sizes.

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;
    }
Insole answered 16/5, 2012 at 16:22 Comment(2)
How about a dirty hack? int meh=system("wget "+name);Conspecific
so, with this code, your buffer is never freed ? when you use a malloc . . . you need a free afaik !Anywise
W
11

HTTP is one of the protocols supported by GIO, so you can open an HTTP URI just like any other file when using the GIO functions instead of standard C functions. Just use g_file_new_for_uri to create the file object and then you can read it just like a local file.

You can use g_file_read to get a GFileInputStream for the given URI and then g_data_input_stream_new to get a GDataInputStream for the input stream, which you can then use to read the file line-by-line. You have to upcast the GFileInputStream to a GInputStream before you can pass it to g_data_input_stream_new (or before you can do anything else useful with it), but if you're programming GTK in C, you're probably used to that by now.

Wool answered 16/5, 2012 at 18:29 Comment(3)
Thanks sepp2k. I am going to try it and once the code works post it for posterity ;)Insole
How do I get the size of the file in advance before allocating a suitable buffer to read it? In C I would do this using fseek and ftell. Is this possible in GTK?Insole
@Insole You can get a GFileInfo object from the file object and then call g_file_info_get_size on it.Wool
A
-1

I'm a noob just as you with GTK (maybe even more) but I suspect that there isn't a "one-instruction" way to download a file in C/C++. You have to use external tools (wget, etc.) or write a GET procedure yourself. Here is an example of file download in C using libcurl. Good luck!

Athanasius answered 16/5, 2012 at 16:40 Comment(2)
To be honest, from the gtk documentation I saw no examples of file handling except for a File Chooser Dialog and therefore even for reading local files I simply coded with C style fread...Insole
The only problem with using libcurl is, I have to install libcurl library too. Actually I am programming for an embedded ARM application and if this lib is unavailable by default I have to then cross compile it..Insole

© 2022 - 2024 — McMap. All rights reserved.