【问题标题】:Fetch a file from web using GLib/GIO from C使用 C 中的 GLib/GIO 从 Web 获取文件
【发布时间】:2012-05-16 16:22:30
【问题描述】:

我应该通过什么函数使用 GLib/GIO 库从 Web 获取文件?

如果我的文件来自:

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

我应该怎么做才能下载它?

对于本地文件,我只使用 fopen 和 fread 等 C 库。

以上应该怎么做?

很遗憾,教程中没有文件处理的示例。我只能从文件对话框中看到一个文件选择器。


使用来自评论的工作代码更新: 下面的代码适用于未知大小的二进制文件。

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;
    }

【问题讨论】:

  • 一个肮脏的黑客怎么样? int meh=system("wget "+name);

标签: c url glib


【解决方案1】:

HTTP 是 GIO 支持的协议之一,因此在使用 GIO 函数而不是标准 C 函数时,您可以像打开任何其他文件一样打开 HTTP URI。只需使用g_file_new_for_uri 创建文件对象,然后您就可以像读取本地文件一样读取它。

您可以使用g_file_read 获取给定URI 的GFileInputStream,然后使用g_data_input_stream_new 获取输入流的GDataInputStream,然后您可以使用它逐行读取文件。您必须先将 GFileInputStream 向上转换为 GInputStream,然后才能将其传递给 g_data_input_stream_new(或在您可以对它做任何其他有用的事情之前),但如果您正在用 C 编写 GTK,那么您现在可能已经习惯了.

【讨论】:

  • 感谢 sepp2k。我将尝试它,一旦代码工作后发布它;)
  • 如何在分配合适的缓冲区读取文件之前提前获取文件的大小?在 C 语言中,我会使用 fseek 和 ftell 来做到这一点。这在 GTK 中可行吗?
  • @user907810 你可以从文件对象中获取一个GFileInfo对象,然后在上面调用g_file_info_get_size。
【解决方案2】:

我和你一样是 GTK 的菜鸟(也许更多),但我怀疑在 C/C++ 中下载文件没有“单指令”方式。您必须使用外部工具(wget 等)或自己编写 GET 程序。 Here 是使用 libcurl 在 C 中下载文件的示例。祝你好运!

【讨论】:

  • 老实说,从 gtk 文档中,除了文件选择器对话框之外,我没有看到任何文件处理示例,因此即使是读取本地文件,我也只是用 C 风格的 fread 编写...
  • 使用 libcurl 的唯一问题是,我也必须安装 libcurl 库。实际上我正在为嵌入式 ARM 应用程序编程,如果默认情况下这个库不可用,我必须交叉编译它..
猜你喜欢
  • 2016-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2023-03-18
  • 2012-10-13
相关资源
最近更新 更多