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

本文主要讲解 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$ l

skype.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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值