DDE后端之dentry(一):从测试经验看运行机制 (move copy trash delete)

来源:互联网 发布:网配圈用什么软件 编辑:程序博客网 时间:2024/06/06 08:40

本文主要讲解 dentry_move  dentry_copy  dentry_trash  dentry_delete 相关机制、联系、区别.

dentry源码:https://github.com/linuxdeepin/dde/tree/develop/lib/dentry

测试代码源码:https://github.com/linuxdeepin/dde/tree/desktop_test/app/desktop/test

核心点:

move  trash  不需要遍历,实质只是将节点inode 从src进行链接到dest

copy delete 就需要遍历了,且遍历方法不同,及 post_hook     pre_hook

核心测试代码:

 

    gpointer* _gp = g_object_ref(g_ptr_array_index(gfileDirectory,0));        ArrayContainer fs = {&_gp,1};    GFile* dest = g_file_new_for_uri("file:///home/ycl");    Test({    g_message("move start");        dentry_move(fs,dest,FALSE);            g_message("move end");    g_message("0copy start");        GFile* _dest0 = g_file_new_for_uri("file:///home/ycl/dde/build/");        GFile* _src0 = g_file_new_for_uri("file:///home/ycl/test_files");        ArrayContainer _fs0;        _fs0.data=&_src0;        _fs0.num = 1;        dentry_copy(_fs0,_dest0);        g_object_unref(_dest0);        ArrayContainer_free0(_fs0);    g_message("0copy end");    g_message("1trash start");        GFile* _src1 = g_file_new_for_uri("file:///home/ycl/test_files");        ArrayContainer _fs1;        _fs1.data=&_src1;        _fs1.num = 1;        dentry_trash(_fs1);        ArrayContainer_free0(_fs1);    g_message("1trash end");    g_message("2copy start");        GFile* _src2 = g_file_new_for_uri("file:///home/ycl/dde/build/test_files");        GFile* _dest2 = g_file_new_for_uri("file:///home/ycl/");        ArrayContainer _fs2;        _fs2.data=&_src2;        _fs2.num = 1;        dentry_copy(_fs2,_dest2);        g_object_unref(_dest2);        ArrayContainer_free0(_fs2);    g_message("2copy end");    g_message("3delete start");        GFile* _src3 = g_file_new_for_uri("file:///home/ycl/test_files");        ArrayContainer _fs3;        _fs3.data=&_src3;        _fs3.num = 1;        dentry_delete_files(_fs3,FALSE);        ArrayContainer_free0(_fs3);    g_message("3delete end");    },"dentry_move");    ArrayContainer_free0(fs);    g_object_unref(dest);

 

一、dentry_move

extern gboolean dentry_move(ArrayContainer fs, GFile* dest, gboolean prompt);

move 调试信息:(move的是文件夹)

------先直接move的整个文件夹(不是copy),然后delete src源

问:为何调试信息中fileops_delete 不是先delete 内部文件再delete  dest的文件夹??

** Message: move start** (desktop:20038): DEBUG: fileops_move: Begin moving files** (desktop:20038): DEBUG: fileops_move: file 0: file:///home/ycl/dde/build/test_files to dest: file:///home/ycl** (desktop:20038): DEBUG: begin _move_files_async** (desktop:20038): DEBUG: _move_files_async: move file:///home/ycl/dde/build/test_files to file:///home/ycl/test_files** (desktop:20038): DEBUG: traverse_directory: chdir to : file:///home/ycl/dde/build/test_files** (desktop:20038): DEBUG: traverse_directory: come out: file:///home/ycl/dde/build/test_files** (desktop:20038): DEBUG: fileops_delete: Begin deleting files** (desktop:20038): DEBUG: fileops_delete: file 0: file:///home/ycl/dde/build/test_files** (desktop:20038): WARNING **: traverse_directory 1: 没有那个文件或目录** (desktop:20038): DEBUG: fileops_delete: End deleting files** (desktop:20038): DEBUG: fileops_move: End moving files** Message: move end

 

 

解释上一个问题:

// 注释掉的部分,是为了解决当move的dest中已有src的文件夹,甚至是文件夹中的内容都有重复的这个bug。 ---错误处理

//retval &= _move_files_async (src, data);//traverse_directory (dir, _move_files_async, _dummy_func, move_dest_gfile);retval &= traverse_directory (src, _move_files_async, _dummy_func, data);if (retval)fileops_delete (&src, 1);//ensure original file is removed.

 

故先需要进行遍历,遍历的目的不是为了删除src的文件夹,而是为了判断dest中是否需要错误处理(是否有共同文件夹和文件)

既然目的明确了,那么在traverse_directory中错误处理完成后,直接删除掉整个src的文件夹就足够了。故fileops_delete (&src, 1)的num为1(既不论是文件夹还是单独文件,直接delete掉就行,不再让delete进行遍历。)

 

 

gboolean dentry_move(ArrayContainer fs, GFile* dest, gboolean prompt)

当dest中已存在要复制的文件时,

prompt=FALSE :不会copy,也不会delete.

prompt=TRUE;提示是否覆盖。程序根据response来决定后续操作

代码位置:

fileops.c中的_move_files_async (GFile* src, gpointer data)中的:

。。。。。。。。。。g_file_move (src, dest,G_FILE_COPY_NOFOLLOW_SYMLINKS,_move_cancellable,NULL,NULL,&error);GFileType type = g_file_query_file_type (src, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL);if (error != NULL){// g_cancellable_cancel (_move_cancellable);g_warning ("_move_files_async: %s", error->message);//TEST:if (g_prompt == TRUE){。。。。。。。。。。。。if (response != NULL && response->apply_to_all)g_move_response = fileops_response_dup (response);}if(response != NULL){switch (response->response_id){case GTK_RESPONSE_CANCEL:

 

 

选择取消时,打印信息如下:

** Message: move start** (desktop:14158): DEBUG: fileops_move: Begin moving files** (desktop:14158): DEBUG: fileops_move: file 0: file:///home/ycl/dde/build/test_files/skype.desktop to dest: file:///home/ycl** (desktop:14158): DEBUG: begin _move_files_async** (desktop:14158): WARNING **: _move_files_async: 目标文件已存在** (desktop:14158): DEBUG: show_conflict_dialog** (desktop:14158): DEBUG: __setup_dialog_labels** (desktop:14158): DEBUG: src: 1373600136** (desktop:14158): DEBUG: src: 1373599855(desktop:14158): fcitx-connection-DEBUG: _fcitx_connection_create_ic(desktop:14158): fcitx-connection-DEBUG: _fcitx_connection_connection_finished** (desktop:14158): DEBUG: bus_method_call** (desktop:14158): DEBUG: response : Cancel** (desktop:14158): DEBUG: move_async: error handling end** (desktop:14158): DEBUG: fileops_move: End moving files** Message: move end

 

 

 

二、dentry_copy

extern void dentry_copy (ArrayContainer fs, GFile* dest);

而copy的调试信息:(copy有文件的文件夹)

------------先mkdir 然后chdir进入文件夹,然后开始依次copy

注:copy完后会come out dest文件夹

** Message: 0copy start** (desktop:20038): DEBUG: fileops_copy: Begin copying files** (desktop:20038): DEBUG: fileops_copy: file 0: file:///home/ycl/test_files to dest_dir: file:///home/ycl/dde/build** (desktop:20038): DEBUG: _copy_files_async: mkdir : file:///home/ycl/dde/build/test_files** (desktop:20038): DEBUG: _copy_files_async: copy file:///home/ycl/test_files to file:///home/ycl/dde/build/test_files** (desktop:20038): DEBUG: traverse_directory: chdir to : file:///home/ycl/test_files** (desktop:20038): DEBUG: traverse_directory: default_background.jpg** (desktop:20038): DEBUG: dest_child_file_uri: file:///home/ycl/dde/build/test_files/default_background.jpg** (desktop:20038): DEBUG: _copy_files_async: copy file:///home/ycl/test_files/default_background.jpg to file:///home/ycl/dde/build/test_files/default_background.jpg** (desktop:20038): DEBUG: traverse_directory: test.desktop。。。。。。。。。。。 (后面同理)** (desktop:20788): DEBUG: _copy_files_async: copy file:///home/ycl/dde/build/test_files/brasero.desktop to file:///home/ycl/test_files/brasero.desktop** (desktop:20788): DEBUG: traverse_directory: come out: file:///home/ycl/dde/build/test_files** (desktop:20788): DEBUG: fileops_copy: End copying files** Message: 2copy end

 

 

extern void dentry_copy (ArrayContainer fs, GFile* dest);

#Bug 当dest中存在要copy的src文件时,打印信息如下:

没有提示是否覆盖,也没有进行copy(无g_debug ("fileops_copy: file %d: %s to dest_dir: %s", i, src_uri, dest_dir_uri);打印信息)。

** Message: 0copy start** (desktop:14712): DEBUG: fileops_copy: Begin copying files** (desktop:14712): DEBUG: fileops_copy: End copying files** Message: 0copy end

 

 

 

三、dentry_trash

extern void dentry_trash(ArrayContainer fs);

trash调试信息:(trash的是文件夹)

---------------——直接trash整个文件夹

** Message: 1trash start** (desktop:20038): DEBUG: fileops_trash: Begin trashing files** (desktop:20038): DEBUG: fileops_trash: file 0: file:///home/ycl/test_files** (desktop:20038): DEBUG: _trash_files_async: trash : file:///home/ycl/test_files** (desktop:20038): DEBUG: fileops_trash: End trashing files** Message: 1trash end

 

注:在被trash的文件夹中直接cd ../ 是进入了trash目录,这说明了,trash相当于改变inode位置

ycl@ycl:~/test_files$ cd ../ycl@ycl:~/.local/share/Trash/files$ lskype.2.desktop  skype.4.desktop  skype.6.desktop  skype.8.desktop  test_files/skype.3.desktop  skype.5.desktop  skype.7.desktop  skype.desktop

 

 

同时也说明,trash后,没有回到src的上一层目录。而是进入了trash文件夹。

#改进

此处是否有隐患??例如上面的 cd ../  ,当然如果桌面有app需要trash后用当前目录,但是却是~/.local/share/Trash/files 目录了。

 

四、dentry_delete

extern void dentry_delete_files(ArrayContainer fs, gboolean show_dialog);

delete的调试信息(delete带有文件的文件夹):

-----------------如下:先chdir 遍历进入文件夹,然后依次delete每个文件

最后come out,delete文件夹

 

 

** Message: 3delete start** (desktop:20788): DEBUG: fileops_delete: Begin deleting files** (desktop:20788): DEBUG: fileops_delete: file 0: file:///home/ycl/test_files** (desktop:20788): DEBUG: traverse_directory: chdir to : file:///home/ycl/test_files** (desktop:20788): DEBUG: traverse_directory: default_background.jpg** (desktop:20788): DEBUG: _delete_files_async: delete : file:///home/ycl/test_files/default_background.jpg** (desktop:20788): DEBUG: traverse_directory: test.desktop** (desktop:20788): DEBUG: _delete_files_async: delete : file:///home/ycl/test_files/test.desktop** (desktop:20788): DEBUG: traverse_directory: test** (desktop:20788): DEBUG: _delete_files_async: delete : file:///home/ycl/test_files/test** (desktop:20788): DEBUG: traverse_directory: test.coffee** (desktop:20788): DEBUG: _delete_files_async: delete : file:///home/ycl/test_files/test.coffee。。。。。。。。。。。。。。。。iles/brasero.desktop** (desktop:20788): DEBUG: traverse_directory: come out: file:///home/ycl/test_files** (desktop:20788): DEBUG: _delete_files_async: delete : file:///home/ycl/test_files** (desktop:20788): DEBUG: fileops_delete: End deleting files** Message: 3delete end

 

 

对于单个文件的操作:

核心代码:

    gpointer* _gp = g_object_ref(g_ptr_array_index(gappinfo,0));        ArrayContainer fs = {&_gp,1};    GFile* dest = g_file_new_for_uri("file:///home/ycl");    Test({    // g_message("move start");        dentry_move(fs,dest,FALSE);            // g_message("move end");    // g_message("0copy start");        GFile* _dest0 = g_file_new_for_uri("file:///home/ycl/dde/build/test_files/");        GFile* _src0 = g_file_new_for_uri("file:///home/ycl/skype.desktop");        ArrayContainer _fs0;        _fs0.data=&_src0;        _fs0.num = 1;        dentry_copy(_fs0,_dest0);        g_object_unref(_dest0);        ArrayContainer_free0(_fs0);    // g_message("0copy end");    // g_message("1trash start");        GFile* _src1 = g_file_new_for_uri("file:///home/ycl/skype.desktop");        ArrayContainer _fs1;        _fs1.data=&_src1;        _fs1.num = 1;        dentry_trash(_fs1);        ArrayContainer_free0(_fs1);    // g_message("1trash end");

打印信息:

[ 26%] Testing dentry_move...** (desktop:6902): DEBUG: fileops_move: Begin moving files** (desktop:6902): DEBUG: fileops_move: file 0: file:///home/ycl/dde/build/test_files/skype.desktop to dest: file:///home/ycl** (desktop:6902): DEBUG: begin _move_files_async** (desktop:6902): DEBUG: _move_files_async: move file:///home/ycl/dde/build/test_files/skype.desktop to file:///home/ycl/skype.desktop** (desktop:6902): DEBUG: fileops_delete: Begin deleting files** (desktop:6902): DEBUG: fileops_delete: file 0: file:///home/ycl/dde/build/test_files/skype.desktop** (desktop:6902): WARNING **: traverse_directory 1: 没有那个文件或目录** (desktop:6902): DEBUG: fileops_delete: End deleting files** (desktop:6902): DEBUG: fileops_move: End moving files** (desktop:6902): DEBUG: fileops_copy: Begin copying files** (desktop:6902): DEBUG: fileops_copy: file 0: file:///home/ycl/skype.desktop to dest_dir: file:///home/ycl/dde/build/test_files** (desktop:6902): DEBUG: _copy_files_async: copy file:///home/ycl/skype.desktop to file:///home/ycl/dde/build/test_files/skype.desktop** (desktop:6902): DEBUG: fileops_copy: End copying files** (desktop:6902): DEBUG: fileops_trash: Begin trashing files** (desktop:6902): DEBUG: fileops_trash: file 0: file:///home/ycl/skype.desktop** (desktop:6902): DEBUG: _trash_files_async: trash : file:///home/ycl/skype.desktop** (desktop:6902): DEBUG: fileops_trash: End trashing files

 

原创粉丝点击