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
).
Я полагаю, что ответ на этот вопрос в значительной степени зависит от того, находятся ли файлы на двух отдельных физических носителях. – Rob
Это не дубликат. Связанный вопрос * не * охватывает, является ли операция *** атомарной ***, скорее, она исправляет проблему при попытке удалить файл. – Rob
это не имеет никакого смысла в реализации, а скорее на уровне ОС. –