【问题标题】:C Glib GIO - How to list files asynchronouslyC Glib GIO - 如何异步列出文件
【发布时间】:2016-05-04 09:04:04
【问题描述】:

我正在使用 GTK 创建一个简单的文件查看器,并且我想异步加载新目录,以防止在加载时挂起整个程序。

在 GIO API 中有g_file_enumerator_next_files_async 函数,允许异步加载块中的文件。但是我怎么知道目录列表何时完成?这是我想出的代码示例:

static void add_file_callback(GObject *direnum,
                GAsyncResult *result,
                gpointer user_data){
    GError *error = NULL;
    GList *file_list = g_file_enumerator_next_files_finish(
                    G_FILE_ENUMERATOR(direnum),
                    result, &error);    
    if( file_list == NULL ){
        g_critical("Unable to add files to list, error: %s", error->message);

    }
    GList *next;
    GFileInfo *info;
    GtkTreeIter iter;
    DirList *list = (DirList*)user_data;
    while(file_list){
        ...add file to list
    }
}


int read_dir(const gchar *path, DirList *list){
    g_assert(list != NULL && list->store != NULL);
    GtkTreeIter iter;
    gtk_list_store_clear(list->store);

    list->path = path;

    GFile *dir = g_file_new_for_path(path);
    GFileEnumerator *dirent = g_file_enumerate_children(dir,
                                        "*",
                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                        NULL,
                                        NULL);
    while( TRUE ){ /* <============================== When to end? */
        g_file_enumerator_next_files_async(dirent,
                        BLOCK_SIZE,
                        G_PRIORITY_DEFAULT,
                        NULL,
                        add_file_callback,
                        list);
    }
    g_file_enumerator_close(dirent, NULL, NULL);
    g_object_unref(dirent);
    g_object_unref(dir);

    return 0;
}

【问题讨论】:

    标签: c asynchronous gtk gio


    【解决方案1】:

    来自this g_file_enumerator_next_files_async reference

    如果出现错误或在枚举数末尾,可以使用少于num_files 个文件调用回调。

    因此,如果回调接收到的文件数量少于BLOCK_SIZE,那么您就知道您有错误或没有更多文件可用

    如果发生这种情况,请设置read_dir 中的循环检查的标志。

    【讨论】:

    • 好主意,我想过标志,但我应该把它放在哪里?
    • @IVaN4B 因为它必须从两个不同的函数中访问,所以它需要是一个全局变量,但由于它不应该被导出,你可以将它设为static
    • 嗯,我已经这样做了,从回调中更改变量似乎不起作用。
    【解决方案2】:

    要列出你应该递归调用g_file_enumerator_next_files_async,而不是循环调用它们,这里是示例:

    static void add_file_callback(GObject *direnum,
                    GAsyncResult *result,
                    gpointer user_data){
        GError *error = NULL;
        GList *file_list = g_file_enumerator_next_files_finish(
                        G_FILE_ENUMERATOR(direnum),
                        result, &error);
        if( error ){
            g_critical("Unable to add files to list, error: %s", error->message);
            g_object_unref(direnum);
            g_error_free(error);
            return;
        }else if( file_list == NULL ){
            /* Done listing */
            g_object_unref(direnum);
            return;
        }else{
    
            GList *node = file_list;
            GFileInfo *info;
            GtkTreeIter iter;
            while(node){
                info = node->data;
                node = node->next;
                ...add to store
                g_object_unref(info);
            }
            g_file_enumerator_next_files_async(G_FILE_ENUMERATOR(direnum),
                            BLOCK_SIZE,
                            G_PRIORITY_LOW,
                            NULL,
                            add_file_callback,
                            list);
        }
        g_list_free(file_list);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多