Предостережение: я публикую это, так как принятый ответ не работает. Однако я не эксперт по блокировке файлов Windows, но вот что мне удалось собрать вместе:
В Windows существует 3 типа блокировки, которые вызывают ошибку EBUSY
в Node.
- Files locked with an 'exclusive lock'
- Executable files locked by the OS which are currently running
- e.g. when you run a
setup.exe
- System protected files
Вариант А:
Node fs построен на основе libuv, которая позволяет передавать дополнительные параметры для запроса эксклюзивной блокировки. Это кажется самым безопасным методом, так как нет шансов изменить/испортить файл.
Откройте файл с помощью UV_FS_O_RDONLY и UV_FS_O_EXLOCK
EBUSY вернулся за 1, 2 и 3.
try {
const fileHandle = await fs.promises.open(filePath, fs.constants.O_RDONLY | 0x10000000);
fileHandle.close();
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}
Примечание: для этого требуется libuv ›= 1.17.0
, что удовлетворяет NodeJS ›= 8.10.0
Вариант Б:
Выполнение fs.rename()
также надежно завершается ошибкой для заблокированного файла, не требует каких-либо специфичных для ОС флагов, но более опасно, поскольку вы можете вызвать ошибки условий гонки, поскольку файл фактически временно перемещается.
EBUSY вернулся за 1, 2 и 3.
try {
await fs.promises.rename(filePath, filePathNew);
await fs.promises.rename(filePathNew, filePath);
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}
Вариант С (не использовать):
Выполните fs.open(..., 'r+')
. Это НЕ РАБОТАЕТ для файлов с монопольной блокировкой 1, ошибка не возвращается.
EBUSY вернулся за 2 и 3.
try {
await fs.promises.open(filePath, 'r+');
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}
person
chris
schedule
16.10.2020