我在Windows环境中使用node。当我使用fs.unlinkSync(fileName)时,它似乎可以工作。在执行unlinkSync语句后,如果我执行fs.existsSync(filename),它将返回false,指示文件不存在,但当我转到物理驱动器时,我仍然可以看到该文件。此时如果我尝试手动删除该文件,它会抛出拒绝访问。但是,只有当我停止执行节点脚本文件时,该文件才会自动从文件系统中删除。这是预期行为吗?
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);
如果代码在文件上先后使用了openSync和closeSync,那么当调用unlinkSync时,文件会立即被删除。但是,如果您要删除closeSync调用,您会发现只有当NodeJS进程干净退出时,文件才会被删除。这只是导致此问题发生的一个示例。如果您使用的是处理文件等的第三方库,则代码可能无法正确关闭文件句柄/描述符,您也会遇到此问题(原因相同)。仅供参考:如果您在基于Linux的操作系统上测试此代码,文件将显示为立即被删除。这是操作系统和文件删除方式之间的行为差异。
openSync
closeSync
unlinkSync
Windows上的NodeJS删除文件时,实际上并不是调用API直接删除文件,而是使用一个名为ZwSetInformation的低级函数(reference)。使用该函数,它将指定文件的名为DeleteFile的字段设置为TRUE(handle)。它的作用是当所有文件句柄都被关闭时,会自动删除,NodeJS中的文件是以FILE_SHARE_DELETE的访问方式打开的,这样就可以通过另一个函数正确的删除。
ZwSetInformation
DeleteFile
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
不会自动关闭文件,需要做的是
返回一个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"));
现在我的删除工作很好!
oalqel3c3#
您可以使用Windows命令行永久删除文件,而不是fs.unlink:
exec(`del ${file}`, (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } });
3条答案
按热度按时间nwsw7zdq1#
如果文件在你的NodeJS代码中被打开但没有关闭,你会遇到你正在经历的行为。在Windows上,它的行为和预期的一样。
以下面的代码为例:
如果代码在文件上先后使用了
openSync
和closeSync
,那么当调用unlinkSync
时,文件会立即被删除。但是,如果您要删除closeSync
调用,您会发现只有当NodeJS进程干净退出时,文件才会被删除。这只是导致此问题发生的一个示例。如果您使用的是处理文件等的第三方库,则代码可能无法正确关闭文件句柄/描述符,您也会遇到此问题(原因相同)。
仅供参考:如果您在基于Linux的操作系统上测试此代码,文件将显示为立即被删除。这是操作系统和文件删除方式之间的行为差异。
详细信息
Windows上的NodeJS删除文件时,实际上并不是调用API直接删除文件,而是使用一个名为
ZwSetInformation
的低级函数(reference)。使用该函数,它将指定文件的名为DeleteFile
的字段设置为TRUE(handle)。它的作用是当所有文件句柄都被关闭时,会自动删除,NodeJS中的文件是以FILE_SHARE_DELETE的访问方式打开的,这样就可以通过另一个函数正确的删除。chy5wohz2#
我有类似的问题,当我用这个来创建一个新的文件
这个用来删除文件
我的文件在杀死节点应用程序后被删除了。原因是
不会自动关闭文件,需要做的是
返回一个Promise,这样我们就可以添加另一个Promise,然后关闭文件
现在我的删除工作很好!
oalqel3c3#
您可以使用Windows命令行永久删除文件,而不是fs.unlink: