删除Node.js中的文件

时间:2013-12-27 07:47:21

标签: windows node.js unlink

我在Windows环境中使用节点。 当我使用fs.unlinkSync(fileName)时,它似乎工作。 执行unlinkSync语句后,如果我执行fs.existsSync(filename),则返回false表示该文件不存在,但是当我转到物理驱动器时,我仍然可以看到该文件。

此时如果我尝试手动删除文件,则会抛出拒绝访问权限。 但是,仅当我停止执行节点脚本文件时,才会自动从文件系统中删除该文件。

这是预期的行为吗?

2 个答案:

答案 0 :(得分:16)

如果文件已在NodeJS代码中打开且未关闭,您将遇到您遇到的行为。它的行为符合预期,在Windows上。

以此代码为例:

var fs = require('fs');

var filename = "D:\\temp\\temp.zip";
var tempFile = fs.openSync(filename, 'r');
// try commenting out the following line to see the different behavior
fs.closeSync(tempFile);

fs.unlinkSync(filename);

如果代码在文件上使用openSync然后使用closeSync,则在调用unlinkSync时会立即删除该文件。但是,如果您要删除closeSync调用,则只有在NodeJS进程干净地退出时才会发现该文件已被删除。这只是导致此问题发生的一种方法的一个示例。

如果您正在使用处理文件等的第三方库,则代码可能无法正确关闭文件句柄/描述符,您也会遇到此问题(出于同样的原因)。

仅供参考:如果您在基于Linux的操作系统上测试此代码,该文件似乎会立即被删除。这是操作系统和文件删除方式之间的行为差​​异。

详细信息

当Windows上的NodeJS删除文件时,它实际上没有调用API来直接删除文件。相反,它使用名为ZwSetInformationreference)的低级函数。使用该函数,它为指定的文件(句柄)设置一个名为DeleteFile的字段为TRUE。这是使用的,以便当该文件关闭所有文件句柄时,它将被自动删除。使用FILE_SHARE_DELETE的访问模式打开NodeJS中的文件,以便可以使用其他功能正确删除它们。

答案 1 :(得分:0)

我在使用它创建新文件时遇到了类似的问题

lib.create = function (directory, fileName, data) {
  return fs.promises.open(`${lib.baseDir}${directory}/${fileName}.json`, "wx")
    .then(fileHandle => {
      // Convert data to string
      const stringData = JSON.stringify(data);

      return fileHandle.writeFile(stringData)
        .then(() => Promise.resolve(`File '${fileName}.json' saved successfully`))
        .catch(() => Promise.reject("Error writing to new file"));
    })
    .catch(() => Promise.reject("Could not create new file, it may already exist"));
}; 

这是删除文件

lib.delete = function (directory, fileName) {
  return fs.promises.unlink(`${lib.baseDir}${directory}/${fileName}.json`)
    .then(() => Promise.resolve(`File '${fileName}.json' deleted successfully`))
    .catch(() => Promise.reject(`Error deleting a ${fileName}.json`))
};

我的文件在杀死节点应用程序后被删除。原因是

fileHandle.writeFile

不要自动关闭文件,需要做的是

fileHandle.writeFile

返回一个 Promise 以便我们可以添加另一个然后关闭文件

return fileHandle.writeFile(stringData)
   .then(() => fileHandle.close())
      .then(() => Promise.resolve(`File '${fileName}.json' saved successfully`))
   .catch(() => Promise.reject("Error writing to new file"));

现在我的删除效果很好!