Ответ 1
File.Replace
использует функцию WinAPI ReplaceFile
внутренне (в Windows, конечно). Однако атомарность не является документированным поведением даже в этой функции, а документация несколько неоднозначна.
Во-первых, если вы хотите согласованности, вы должны использовать файл резервной копии. Согласно документации:
[При перемещении файла сбой...] Если указано lpBackupFileName, замененные и заменяющие файлы сохраняют свои исходные имена файлов. В противном случае замененный файл больше не существует, и файл замены существует под его первоначальным именем.
Другой режим отказа приводит к
[При перемещении файла сбой...] Файл замены по-прежнему существует под его первоначальным именем; однако он унаследовал файловые потоки и атрибуты из файла, который он заменяет. Файл, который нужно заменить, все еще существует с другим именем. Если указано lpBackupFileName, это будет имя замененного файла.
Это худшее из поведения документа - у вас все еще есть оба файла, но файл, который будет "скопирован", уже имеет свои атрибуты безопасности. Если вы используете службу с ограниченными правами для записи файла, это может создать проблему.
Наконец, когда удаление не выполняется, ничего не происходит.
Итак, вся операция атома? Несмотря на то, что это официально не задокументировано, у нас есть несколько указателей. Во-первых, операция замены - это, в конечном счете, своп идентификаторов файлов (и одностороннее обновление всех атрибутов файла), если вы используете опцию резервного файла; что операция, транзакционная на NTFS, поэтому я ожидал, что эта часть будет фактически атомарной, если вам не нужно беспокоиться об атрибутах файлов, ACL и альтернативных потоках данных.
Однако это поведение не является договорным, ни для File.Replace
, ни для ReplaceFile
. Если вам нужен контрактный способ реализации трансакционных операций, вам необходимо использовать TxF. Две основные проблемы: один, TxF поддерживается только с Vista, и два, он практически не использовался на практике и устарел. Bummer:) Официальный рекомендуемый Microsoft способ замены TxF описан в https://msdn.microsoft.com/en-us/library/windows/desktop/hh802690%28v=vs.85%29.aspx - и включает использование ReplaceFile
(отображается в .NET как File.Replace
).