js

自己写的死亡递归,哭着也要改完

Posted by wml on November 27, 2018

挖坑

最近正在写一个CLI工具,经常需要使用node的文件流操作,正好需求是读取文件流,再写入指定文件中,不可避免的需要使用到递归遍历目录。于是在行云流水地写完一个自认为还比较完美的递归以后(~ ̄▽ ̄)~ ,大致如下:

function create(temp, target) {
    const files = fs.readdirSync(temp);
    files.foreach(file => {
        const stats = fs.statSync(`${temp}/${file}`);
        if(stats.isFile()) {
            /* some code */
        }else if(stats.isDirectory()) {
            fs.mkdirSync(`${target}/${file}`);
            create(temp, target);  // 这里竟然又原封不动的把路径传回去了
        }

    })
}

也没去认真检查逻辑是否正确,美滋滋地执行脚本,干净利落的敲下回车٩(๑❛ᴗ❛๑)۶,只见命令行窗口以肉眼赶不上的速度输出了一堆我本来只是打算读取的文件 ヾ(◍°∇°◍)ノ゙。。如下冰山一角的图示:

rm

颤颤巍巍地赶紧猛按ctrl+c,但终究还是赶不上计算机的速度,不可避免的创建了大概小一千的文件目录结构吧(是的,后来悄咪咪大概数了下)。 rm

不死心地打开本地目录,层层叠叠的目录告诉我刚刚确实结结实实给自己挖了个坑。

rm

挣扎填坑

毕竟也是见过大风大浪(假装见过吧)的人,很快就调整了递归函数,传入正确路径后程序是完美跑起来了。

接下来就是删除这令人窒息的目录“毁尸灭迹”了ヾ(๑╹◡╹)ノ”,直接删除是不可能直接删除的,Windows文件夹有长度限制,在路径太深,长度达到600多个字符时,删除文件时出现报错:

“源文件名长度大于文件系统支持的长度。请尝试将其移动到具有较短路径名称的位置,或者在执行此操作前尝试将其重命名为较短的名称”。

手动进到window限制长度的文件夹内删掉剩余的目录?这个方法看起来可行,但是都不确定到底这个文件路径多深,这种费时费力的方法肯定不是一个合格的程序猿首选(。・ω・。)。

网上查阅了许多听说成功的方法:

  • 1、 压缩文件时,点击删除源文件。

这个方法不可行,还是会提示删除失败,源文件太长。

  • 2、 del /f /s /q 文件名

cmd下del确实可以删除普通文件,相关参数也如下图,但对于太深的目录依旧是无能为力,提示源文件不为空。

rm

  • 3、robocopy empty_dir will_delete_dir /purge

Robocopy, or “Robust File Copy”, is a command-line directory and/or file replication command.

这个命令也是呼声最高的方法了,简单来说就是用来复制文件或目录,用空文件替换源文件,/PURGE: 删除源中不再存在的目标文件/目录。姑且一试,敲下命令的瞬间,和最开始的死亡递归一样飞速查询。

rm

仿佛看到希望的我,默默等它跑完,期待地打开本地目录,发现除了里面的文件貌似不见了外,那几百个嵌套的空目录依旧赫然在目。

填坑之rm -rf

尝试了这么多方法依旧不行,有些泄气的我甚至想要格式化硬盘了,但是庞大的数据又让我望而生怯。只能重新寻找方法,突然在stackoverflow上看到只有3票赞成的回答里熟悉的rm -rf,和死亡递归一样令人害怕的就是这个“程序猿从删库到跑路”的命令了吧。

毕竟有备份,所以在仔细地输入rm -rf demo/(毕竟恢复备份也麻烦==)命令后,小心翼翼打下回车,因为只剩空文件夹了,所以速度很快,菌脏打开本地文件,真的删除了诶!٩(๑>◡<๑)۶ 不得不感慨下利刃就是利刃,挥得好所向披靡,挥得不好就只能伤及自身==

总结

经过此次有惊无险地递归经历,也意识到自己对于递归的理解不够深刻,不然也不至于犯如此低级的错误,总的来说,知识点这种东西,基础还是要打牢,这次是侥幸没有什么大的影响,但是也给自己敲下警钟,学海无涯,每一个知识点都是往上攀爬的基石,一旦不稳,也许就会让自己摔得四脚朝天了。。。