Node.js中如何重命名具有子目录的目录(EPERM,EXDEV)

3

我正在尝试使用node.js编写一个服务器,它将像简化版的谷歌云盘/OneDrive一样工作。我编写了一个重命名文件/目录的方法,但它并不适用于所有情况。以下是代码:

try {
  if (!fs.existsSync(fullPath)) {
    reject(new Error('The file to be renamed does not exist!'));
  } else if (fs.existsSync(newPath)) {
    reject(new Error('A file already exists with that name!'));
  } else {
    fs.renameSync(fullPath, newPath);
    resolve(newPath);
  }
} catch (err) {
  reject(err);
}

在没有子目录的情况下,它可以轻松地重命名文件或包含没有子目录的目录。但是当一个目录有一个或多个子目录时,重命名失败。

我正在使用Windows平台,出现以下错误。在使用 fs.chmodSync(fullPath, 0o777) 更改文件权限之前尝试过,但错误仍然存在。

"errno": -4048,
"syscall": "rename",
"code": "EPERM",

我认为问题出在Windows和它的文件系统使用上,所以我尝试将整个东西运行在Docker容器中(最终产品将部署在Docker上),但是我遇到了以下错误:

"errno": -18,
"syscall": "rename",
"code": "EXDEV",

问题在于我的路径已经标准化,而且不存在从一个驱动器复制到另一个驱动器的情况。如果我console.log我的完整路径(fullPath)和新路径(newPath),我得到类似下面的结果:
src/test-storage/myFolder/aFolder
src/test-storage/myFolder/xFolder

非常感谢您的帮助,提前致谢。祝您有美好的一天! :)

1个回答

2

我的第一个答案没有帮助,所以我删除了它,这里是一个新的答案。

我遇到了同样的问题,只不过我使用了 'fs-extra' 模块并尝试移动一个包含另一个文件夹的文件夹。当我检查 'moveSync' 方法时,我发现它使用了来自 'fs' 模块的相同的 'renameSync'。

我还没有找到这个错误的原因,但这里有一个解决方法:

  1. 递归地复制你的文件夹。我使用了相同的 fs-extra 模块,但 ncp 也可以实现。

所以,首先导入模块

import * as fs from 'fs-extra';

然后复制您的文件夹:

fs.copySync('/tmp/folderName', '/tmp/newFolderName');
  1. 接下来只需删除原始文件夹,fs-extra和ncp在幕后使用rimraf模块,但我最终使用了带有recursive: true选项的fs.rmdirSync:

fs.rmdirSync(path, { recursive: true });

尽管我尝试时没有产生错误,但仍建议使用原始的fs.renameSync重命名文件。

如果有人能解释为什么fs.renameSync无法处理包含另一个文件夹的文件夹,并分享一下,那就太好了。

更新:这是我用于重命名文件夹和文件的方法:

rename(path: string, newPath: string) {
    if (fs.existsSync(newPath)) {
      throw new Error('Already exists');
    }
    
    if (fs.lstatSync(path).isDirectory()) {
      fs.copySync(path, newPath);
      fs.rmdirSync(path, { recursive: true });
    } else if (fs.lstatSync(path).isFile()) {
      fs.renameSync(path, newPath);
    }
  }

谢谢 :) 我把这个项目搁置了一段时间,但我会在有空的时候研究一下。 - undefined
@Zsombor 不客气 :) 我已经添加了我使用的方法的完整代码。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接