Атомная операция File.Move

Я пытаюсь создать огромный текстовый файл с помощью С#, а другой процесс постоянно просматривает местоположение и пытается подобрать файл, если он доступен.

Чтобы сделать файл атомарным, выполните следующие действия:

1 - Write to file : Filename_temp.txt
2 - Check if Filename.txt already exists then Delete
3 - Do a File.Move to the same destination     
    From filename : Filename_temp.txt 
    TO : Filename.txt

Поскольку у С# нет переименования, я должен полагаться на File.Move, гарантирует ли это, что операция перемещения будет атомарной, или есть другой способ добиться этой атомарности?


person Murtaza Mandvi    schedule 07.03.2013    source источник
comment
что вы точно имеете в виду, говоря: атомный ход?   -  person Tigran    schedule 07.03.2013
comment
Можете ли вы обновить логику обоих приложений? Если да - используйте Mutex для синхронизации доступа   -  person sll    schedule 07.03.2013
comment
Рекомендую сначала проверить наличие и удалить. Вы никогда не знаете, когда Filename_temp.txt может уже существовать.   -  person Nolonar    schedule 07.03.2013
comment
Это ограничение Windows, а не С#   -  person Jodrell    schedule 07.03.2013
comment
@Tigran, он хочет, чтобы файл был завершен до того, как он станет видимым для другого процесса.   -  person Anthony Pegram    schedule 07.03.2013
comment
@Tigran Atomic в этом контексте означает все или ничего, поэтому в основном файл недоступен наблюдателю, пока он не будет полностью написан.   -  person Murtaza Mandvi    schedule 07.03.2013
comment
@sll другое приложение находится вне моего контроля, и у меня нет прав на изменение этого приложения.   -  person Murtaza Mandvi    schedule 07.03.2013
comment
По сути, это тот же вопрос /atomic-file-copy-under-net   -  person Jodrell    schedule 07.03.2013


Ответы (4)


Согласно статье в блоге MSDN Как выполнять атомарную запись в файл, переименование файла NTFS является атомарной операцией:

Решение? Давайте помнить, что изменения метаданных являются атомарными. Переименовать как раз такой случай. Итак, мы можем просто выполнить запись во временный файл, и после того, как мы узнаем, что записи на диск (завершенные и сброшенные), мы можем поменять местами старый файл с новым файлом.

Конечно, это не гарантирует, что File.Move просто выполнит операцию переименования NTFS, но я не могу придумать вескую причину, по которой она должна делать что-то более сложное.

person Heinzi    schedule 07.03.2013
comment
Конечно, есть причина: файл мог быть перемещен на другое устройство. - person PythonNut; 14.07.2015

File.Move должен быть «переименованием», если источник и место назначения находятся на одном томе. Таким образом, независимо от размера файла перемещение должно быть «мгновенным». Я полагаю, это ваша забота?

Из часто задаваемых вопросов от сотрудника MS на http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365240%28v=vs.85%29.aspx у нас есть;

'Часто задаваемый вопрос: является ли MoveFileEx атомарным, если существующие и новые файлы находятся на одном диске?

Простой ответ: «обычно, но в некоторых случаях он молча откатывается к неатомарному методу, поэтому не рассчитывайте на него».

Я думаю, если это на 100% критично, вы могли бы взглянуть на транзакционную NTFS. Я не уверен, есть ли в .Net для этого обертки, поэтому вам может понадобиться использовать P/Invoke.

person Gareth Wilson    schedule 07.03.2013
comment
Точно, это где-то задокументировано? - person Murtaza Mandvi; 07.03.2013
comment
На данный момент ничего не могу найти, это скорее особенность NTFS, а не .Net. Постараюсь найти ссылки. - person Gareth Wilson; 07.03.2013
comment
+1. Похоже, что на этот счет есть противоречивые источники от Microsoft. - person Heinzi; 07.03.2013

Это функция Windows, а не С# или .Net Framework.

Глянь сюда

атомарность File.Move

person Jodrell    schedule 07.03.2013

Вы можете записать свой файл непосредственно в место назначения и использовать сигнальный файл нулевого размера, который создается после того, как ваш огромный файл будет готов. Ваш процесс чтения может искать сигнальный файл и читать огромный файл после того, как сигнальный файл станет доступным. Я думаю, что это может решить проблему «атомарности».

person Slava    schedule 07.03.2013
comment
В основном файлы семафора указывают DONE, однако это требует изменения процесса наблюдения, что, к сожалению, выходит за рамки моих возможностей. - person Murtaza Mandvi; 07.03.2013