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;
    }
Philip Withnall
  • 5,293
  • 14
  • 28
user907810
  • 3,208
  • 10
  • 39
  • 47

2 Answers2

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.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • Thanks sepp2k. I am going to try it and once the code works post it for posterity ;) – user907810 May 21 '12 at 08:31
  • 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? – user907810 May 21 '12 at 10:51
  • @user907810 You can get a GFileInfo object from the file object and then call g_file_info_get_size on it. – sepp2k May 21 '12 at 11:14
-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!

Community
  • 1
  • 1
Avio
  • 2,700
  • 6
  • 30
  • 50
  • 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... – user907810 May 21 '12 at 08:34
  • 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.. – user907810 May 21 '12 at 08:36