Подтвердить что ты не робот

Node js: файл fs.rename перезаписывает, если он уже существует

Перезаписывает ли fs.rename файл, если он уже существует?

var fs = require('fs'),
    oldPath = 'firstfile.txt',
    newPath = 'temp/firstfile.txt';

fs.rename(oldPath, newPath, function (err) {
    console.log('rename callback ', err); 
});

Что произойдет, если существует '/newFolder/somefile.txt'?

4b9b3361

Ответ 1

Короткий ответ: да


Длинный ответ:

Я создал script, чтобы проверить его:

var fs = require('fs');

Создайте два файла:

fs.writeFileSync('a.txt',"This is a file")
fs.writeFileSync('b.txt',"This is another file")

Rename:

fs.renameSync('a.txt','b.txt');

Проверьте, не было ли это превышено:

var text = fs.readFileSync('b.txt', "utf-8");

console.log(text) // This is a file

Ответ 2

Похоже, что fr.rename предоставляет ту же функциональность, что и команда rename (2) Linux (источник: Переместить файл в ExpressJS/NodeJS). Сказав это, если вы посмотрите на документы для команды rename (2), они говорят, что если имя файла, которое вы переименовываете, уже существует, существующее имя файла будет заменено и перезаписано (source: http://linux.die.net/man/2/rename)

Ответ 3

nodejss fs.rename() перезаписывает файлы, потому что именно так определяется Unix rename(), а fs.rename() документируется как обертка syscall rename() Unix. Я не знаю ни одного места в документах nodejs, которые прямо указывают это на fs.rename(). Однако есть несколько замечаний, которые позволяют нам это определить:

  • Документы nodejs ссылаются на man-страницу Linux для rename(2) при описании функциональности fs.rename. Постоянная ссылка GitHub на документы не связывает его, но процессинг автоматически превращает rename(2) в rename(2).

  • В разделе "Syscalls and man pages" документации указано, что syscalls эмулирует поведение unix в Windows. Я выхожу из фразы "иногда невозможно заменить семантику sysall для Unix в Windows" , что подразумевает, что nodejs внедрил семантику Unix в Windows, когда это возможно:

    Большинство системных вызовов Unix имеют эквиваленты Windows, но поведение может отличаться в Windows относительно Linux и macOS. Для примера тонких способов, с помощью которых иногда невозможно заменить семантику sysall для Unix в Windows, см. Node issue 4760.

  • Я видел другие дискуссии о таких вещах, и люди всегда ссылаются на то, как nodejs просто использует libuv для вещей, поэтому нужно просто взглянуть на libuv. Цель libuvs - предоставить переносимую асинхронную реализацию POSIX API, и, таким образом, одна из ее целей - вести себя как unix даже в Windows. В libuv docs не обсуждается rename(), но реализация Windows fs__rename() вызывает MoveFileEx() с MOVEFILE_REPLACE_EXISTING.

  • О, и я почти забыл. Даже если вы знаете, что nodejs определяет fs.rename() как POSIX rename(), возможно, вы не знаете поведение, определяемое POSIX rename() относительно перезаписи

    Если ссылка, названная новым аргументом, существует, она должна быть удалена и переименована в новую. В этом случае ссылка с именем new должна оставаться видимой для других потоков во время операции переименования и ссылаться либо на файл, который был указан новым или старым до начала операции.

    Просто это описывает замену транзакционного файла, если цель переименования уже существует. Если файл с новым именем уже существует до вызова rename(), он никогда не перестанет существовать, даже если ваша программа выйдет из строя или поле потеряет питание. В некоторый момент времени новое имя начнет ссылаться на файл со старым именем.

    Вы должны предпочесть этот метод для удаления исходного файла и последующего переименования вновь созданного, потому что файл на новом пути перестанет существовать на мгновение (возможно, вызвав условие гонки для чего-то, пытающегося его открыть) или, если процесс уничтожается или сбой питания происходит в нужное время, навсегда.

Примечание: из-за проблем с переносимостью полезно рассмотреть использование помощников переносимости, таких как graceful-fs и cross-spawn, когда вы хотите, чтобы ваш код также работал для пользователей Windows. Я понимаю, что это не вопрос адеектов, но я предположил, что искатель задал бы такой вопрос только из-за фона win32, где переименовать кант перезаписывать файлы или потому, что он задал бы такой вопрос, только если он заинтересован в переносимости за пределами Unix.