typescript - (module node.js) bộ xử lý ảnh sharp giữ file gốc mở, không thể xóa file gốc sau khi thay đổi kích thước
Tôi đang sử dụng sharp để thay đổi kích thước một hình ảnh đã tải lên trong ứng dụng Node.js/Express được viết bằng Typescript. Sau khi thay đổi kích thước thành công, tôi muốn xóa tệp gốc. Đối với các hình ảnh png và gif, thao tác kết thúc thành công, tôi có hình ảnh đã thay đổi kích thước và tệp gốc đã bị xóa. Đối với các hình ảnh jpg và tif, việc thay đổi kích thước thành công, tuy nhiên lệnh unlink thất bại với lỗi sau:
EBUSY: tài nguyên đang bận hoặc bị khóa, hủy liên kết '...'
như thể sharp().resize() vẫn sẽ giữ khóa tệp đầu vào, ngay cả sau khi quá trình thay đổi kích thước hoàn tất.
Đây là mã để kiểm tra hành vi đã mô tả:
import { existsSync, unlinkSync } from "fs";
import { normalize, parse } from "path";
var argv = require("yargs").argv;
var sharp = require("sharp");
var appRoot = require("app-root-path") + "/";
let resizeTest = async function (filename: string): Promise<boolean> {
try {
let nameParts = parse(filename);
let source = appRoot + filename;
let destination = appRoot + nameParts.name + "_resized" + nameParts.ext;
let fileExists = await existsSync(source);
if (!fileExists) {
console.log("Input file not found. Exiting.");
return false;
}
let resizeResult = await sharp(source)
.resize(128, 128)
.toFile(destination);
console.log("Resize operation terminated: ", resizeResult);
await unlinkSync(source);
console.log("unlinkSync operation terminated.");
return true;
} catch (error) {
console.log("An error occured during resizeTest execution: ", error.message);
return false;
}
}
if (argv._.length === 0) {
console.log("Usage: node sharptest.js FILENAME");
} else {
let resizeResult: Promise<boolean> = resizeTest(argv._[0]);
resizeResult.then(result => console.log("Returning from execution with ", result));
}
Tôi đang bỏ lỡ điều gì?
Câu trả lời #1
Ban đầu tôi bị bối rối bởi việc bạn sử dụng dấu gạch chéo xuôi, giả định rằng bạn sẽ sử dụng một hệ điều hành kiểu Unix, nơi việc gọi unlink trên một file vẫn còn đang mở thường không phải là vấn đề.
Tuy nhiên, trên Windows, tôi nghĩ rằng các tệp đang mở thường được bảo vệ khỏi việc xóa, và vấn đề này mô tả một vấn đề tương tự, và cũng một giải pháp: bên trong, sharp duy trì một bộ nhớ đệm của các tệp (đang mở), điều này sẽ ngăn tệp gốc bị xóa.
Nếu bạn tắt bộ nhớ đệm đó, vấn đề nên được khắc phục:
// add this at the top of your code
sharp.cache({ files : 0 });
Được ghi lại ở đây.
CHỈNH SỬA: như đã lưu ý trong một số nhận xét, mã ở trên có thể không khắc phục được sự cố. Thay vào đó, hãy sử dụng cái này:
sharp.cache(false);
Câu trả lời #2
Về mặt nội bộ, Sharp duy trì một bộ nhớ đệm các tệp (đang mở), điều này sẽ ngăn tệp gốc bị xóa.
sharp.cache(false);
thêm dòng trên vào phần bắt đầu của REST API của bạn
