node.js - NodeJS 本身在 Windows 上保存文件 EBUSY?
问题描述
我创建了一个简单的函数来处理上传的文件。我正在使用 multer 将多部分数据处理成文件。然后我使用下面的代码来移动文件,并返回数据,以便我的网页知道如何显示图像。
似乎 NodeJS 以某种方式使文件保持打开状态。我还创建了一个删除文件的函数,但这会给我一个 EBUSY 错误。如果我尝试通过 Windows 删除,它会说 NodeJS 已锁定文件。当我重新启动 NodeJS 进程然后重新请求删除 URL 时,该文件被正确删除。
有什么方法可以强制 NodeJS 关闭文件资源吗?或者我的脚本中是否还有其他一些我遗漏的错误?
我将节点更新到版本 12.4.0 但这也没有帮助。
处理上传:
exports.handleFormNotes = async(req, res, next) => {
try {
const configVariables = req.app.get('configVariables');
const uploadSuffix = req.body.uploadFolderSuffix || '';
console.log('upload suffix', uploadSuffix);
if (!req.files.length) {
return;
}
const uploadedFiles = Array();
var destPath = configVariables['FormNotesUploadDirectory'];
if (uploadSuffix !== '')
destPath = destPath + '/' + uploadSuffix;
destPath = path.resolve(destPath);
// mkdirSync returns undefined, so run that first and see if the directory exists second.
if (!fs.mkdirSync(destPath, { recursive: true }) && !fs.existsSync(destPath)) {
console.log(destPath, 'does not exist!');
req.alertHandler.addAlert('Pad om afbeelding op te slaan is niet bereikbaar: ' + destPath, 'danger');
res.render('error');
return;
}
var baseUrlPath = configVariables['FormNotesUploadDocumentRoot'];
if (uploadSuffix != null) {
baseUrlPath = baseUrlPath + '/' + uploadSuffix;
}
for(const uploadedFile of req.files) {
let now = new Date();
let destFilename = getDateTime() + "_" + uploadedFile.originalname;
let destFilenameThumb = 'thumb_' + destFilename;
var fullDestination = path.resolve(destPath + '/' + destFilename);
var fullDestinationThumb = path.resolve(destPath + '/' + destFilenameThumb);
console.log('Copy src:', uploadedFile.path, fullDestination);
fs.copyFileSync(uploadedFile.path, fullDestination);
var unlinkResult = fs.unlinkSync(uploadedFile.path);
console.log('Unlink "' + uploadedFile.path + '", result after upload:', unlinkResult);
var newFileInfo = await sharp(destPath + '/' + destFilename)
.resize({ width: 120 })
.toFile(fullDestinationThumb);
console.log('new file info thumb:', newFileInfo);
uploadedFiles.push({
'fullImg': baseUrlPath + '/' + destFilename,
'thumbImg' : baseUrlPath + '/' + destFilenameThumb,
'original': uploadedFile.originalname
});
}
// Push to backend
const data = {
files: [...uploadedFiles],
uploadSuffix: uploadSuffix
};
// Normally retVal should be the return data from OI. If anything goes wrong, retVal = 'error'
this.saveAttachment(req, res, data);
return res.send(data);
}
catch (err) {
console.log('Error handling from notes:', err);
req.alertHandler.addAlert('Error handling form notes: ' + err);
return 'error';
}
}
删除上传:
exports.rmFormNote = async(req, res, data) => {
let retVal;
try {
const configVariables = req.app.get('configVariables');
const httpPath = req.query.img;
console.log('http path:', httpPath);
// Strip off the document root, but check if they are the same first
const firstPart = httpPath.substring(0, configVariables['FormNotesUploadDocumentRoot'].length);
console.log('same?', firstPart, configVariables['FormNotesUploadDocumentRoot']);
var relPath = httpPath;
if (firstPart == configVariables['FormNotesUploadDocumentRoot']) {
relPath = httpPath.substring(configVariables['FormNotesUploadDocumentRoot'].length + 1);
}
var parts = relPath.split('/');
parts[parts.length-1] = 'thumb_' + parts[parts.length-1];
var thumbPath = parts.join('/');
thumbPath = path.resolve(configVariables['FormNotesUploadDirectory'] + '/' + thumbPath);
console.log('thumbpath: ', thumbPath);
var fullPath = configVariables['FormNotesUploadDirectory'] + '/' + relPath;
var dest = path.resolve(fullPath);
console.log('dest: ', dest);
if (!fs.existsSync(dest))
throw "File not found";
fs.unlink(dest, (err) => {
if (err) throw err;
console.log('File deleted');
});
retVal = { result: true };
}
catch(err) {
console.log('Ohnoo', err);
retVal = { result: false, msg: err };
}
return res.send(retVal);
}
解决方案
原来缩略图创建者锐利是问题所在,如this github issue中所述。
我只需要禁用缓存,如下所示:
sharp.cache(false);
var newFileInfo = await sharp(destPath + '/' + destFilename)
.resize({ width: 120 })
.toFile(fullDestinationThumb);
推荐阅读
- java - SonarQune 抱怨从 wsdl 文件生成的 _equalsCalc 变量不是瞬态的或可序列化的
- reactjs - 将 ref 传递给具有循环 ID 的函数?
- python - Tensorflow 对象检测 API 中的步骤是什么意思
- javascript - node_modules/_crypto-js@3.1.9-1@crypto-js/SHA256.web.js 不存在
- javascript - Nestjs Apollo graphql 上传标量
- android - Android:有没有办法在自定义列表视图的单个 onItemClickListner() 方法中添加多个意图?
- java - CryptoJS 三重 DES 代码与 Java 等效
- react-native - React Native Admob for Google Admob 中 AdmobBanner 和 PublisherBanner 的区别?
- javascript - 当子 div 包含特定文本时,如何隐藏父 div?
- kendo-ui - Kendo 中数据源查询后的空列