如果目标文件不存在,则在 Node.js 中异步重命名文件

Posted

技术标签:

【中文标题】如果目标文件不存在,则在 Node.js 中异步重命名文件【英文标题】:Rename files asynchronously in Node.js if destination files don't exist 【发布时间】:2019-12-28 16:32:40 【问题描述】:

仅当目标文件不存在时,我才尝试在 Node.js 中异步重命名文件。

我做了如下快速测试:

const fs = require('fs')

const files = [ 'file1', 'file2', 'file3' ]
const new_name = 'new-name' // same destination name for all 

fs.exists() - 已弃用

for (let file of files)

  fs.exists(new_name, (exists) => 
    if (!exists) fs.rename(file, new_name, (err) => )
   )

fs.access() - 推荐

for (let file of files)

  fs.access(new_name, fs.constants.F_OK, (err) => 
    if (err) fs.rename(file, new_name, (err) => )
  )

fs.move() - 来自fs-extra

const fs_extra = require('fs-extra')

for (let file of files) 

  fs_extra.move(file, new_name,  overwrite: false , (err) => )

每次所有 3 个文件都被覆盖并重命名为一个文件。


我相信这是因为所有exists 检查都比任何rename 发生更早触发。

我知道如何同步完成这项任务,但想确定没有合适的异步方式来执行此操作。

【问题讨论】:

您是否考虑过为此使用异步等待? 在 nodejs 中使用异步模块并使用 async.waterfall 。查看此链接以查看异步模块中的各种选项。 medium.com/velotio-perspectives/… @cr05s19xx 不。遗憾的是,我不知道如何正确地做到这一点。 【参考方案1】:

@ponury-kostek 解决方案效果很好,并被标记为已接受的答案。

我最终得到了以下代码,因为它有点短:

async function rename_files() 

  for (let file of files)                
      await fs.move(file, new_name)

rename_files()  

【讨论】:

【参考方案2】:

你可以在文件重命名时创建Promiseresolve

fs.rename(file, new_name, (err) => 
    resolve(); <------
);

或跳过重命名时

fs.access(new_name, fs.constants.F_OK, (err) => 
    if (err) 
        return fs.rename(file, new_name, (err) => 
            resolve();
        );
    
    resolve(); <------
);

完整代码

(async () => 
    for (let file of files) 
        await new Promise((resolve) => 
            fs.access(new_name, fs.constants.F_OK, (err) => 
                if (err) 
                    return fs.rename(file, new_name, (err) => 
                        resolve();
                    );
                
                resolve();
            );
        );
    
)();

如果您不想将async/awaitPromise 混合使用

(async () => 
    function rename(file, new_name) 
        return new Promise((resolve) => 
            fs.access(new_name, fs.constants.F_OK, (err) => 
                if (err) 
                    return fs.rename(file, new_name, (err) => 
                        resolve();
                    );
                
                resolve();
            );
        );
    

    for (let file of files) 
        await rename(file, new_name);
    
)();

【讨论】:

效果很好。感谢您的回答。你知道如何使用 async.waterfall 实现这一点吗?

以上是关于如果目标文件不存在,则在 Node.js 中异步重命名文件的主要内容,如果未能解决你的问题,请参考以下文章

Node.js学习之路05——fs文件系统之文件的写入和读取

玩转Node.js - 04. 第一个异步 I/O!

linux学习

Node.js 云功能“get() 中的 firestore set() 如果不存在”无法正常工作?

Node.js 中 fs.renameSync 报错

如果使用 openSync 打开文件,如何在 node.js 中获取文件描述符