C Glib GIO - 如何异步列出文件

时间:2016-01-27 12:05:26

标签: c asynchronous gtk gio

我正在使用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;
}

2 个答案:

答案 0 :(得分:0)

来自this g_file_enumerator_next_files_async reference

  

如果出现错误或在枚举数结束时,可以使用少于BLOCK_SIZE个文件调用回调。

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

如果发生这种情况,请设置var date = new Date(date1); date.setHours(0, 0, 0, 0); var diff = date2.getTime() - date.getTime(); return diff >= 0 && diff < 86400000; 中的循环检查的标记。

答案 1 :(得分:0)

要进行列表,你应该递归调用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);
}