删除Node.js中的文件

jvidinwx  于 2023-02-21  发布在  Node.js
关注(0)|答案(3)|浏览(221)

我在Windows环境中使用node。当我使用fs.unlinkSync(fileName)时,它似乎可以工作。在执行unlinkSync语句后,如果我执行fs.existsSync(filename),它将返回false,指示文件不存在,但当我转到物理驱动器时,我仍然可以看到该文件。
此时如果我尝试手动删除该文件,它会抛出拒绝访问。但是,只有当我停止执行节点脚本文件时,该文件才会自动从文件系统中删除。
这是预期行为吗?

nwsw7zdq

nwsw7zdq1#

如果文件在你的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);

如果代码在文件上先后使用了openSynccloseSync,那么当调用unlinkSync时,文件会立即被删除。但是,如果您要删除closeSync调用,您会发现只有当NodeJS进程干净退出时,文件才会被删除。这只是导致此问题发生的一个示例。
如果您使用的是处理文件等的第三方库,则代码可能无法正确关闭文件句柄/描述符,您也会遇到此问题(原因相同)。
仅供参考:如果您在基于Linux的操作系统上测试此代码,文件将显示为立即被删除。这是操作系统和文件删除方式之间的行为差异。

详细信息

Windows上的NodeJS删除文件时,实际上并不是调用API直接删除文件,而是使用一个名为ZwSetInformation的低级函数(reference)。使用该函数,它将指定文件的名为DeleteFile的字段设置为TRUE(handle)。它的作用是当所有文件句柄都被关闭时,会自动删除,NodeJS中的文件是以FILE_SHARE_DELETE的访问方式打开的,这样就可以通过另一个函数正确的删除。

chy5wohz

chy5wohz2#

我有类似的问题,当我用这个来创建一个新的文件

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,这样我们就可以添加另一个Promise,然后关闭文件

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

现在我的删除工作很好!

oalqel3c

oalqel3c3#

您可以使用Windows命令行永久删除文件,而不是fs.unlink:

exec(`del ${file}`, (error, stdout, stderr) => {
        if (error) {
          console.error(`exec error: ${error}`);
          return;
        }
      });

相关问题