Есть ли в Go независимый от ОС способ атомарной перезаписи файла?

Если файл уже существует, я хочу перезаписать его. Если его не существует, я хочу создать его и написать в него. Я бы предпочел не использовать стороннюю библиотеку, такую ​​как lockfile (которая, кажется, обрабатывает все типы блокировок).

Моей первоначальной идеей было:

  1. Записать во временный файл со случайно сгенерированным большим идентификатором, чтобы избежать конфликта.
  2. Переименуйте временное имя файла -> новый путь.

1 ответ

Решение

os.Rename звонки syscall.Rename который для Linux/UNIX использует переименованный системный вызов (который является атомарным *). На винде syscall.Rename звонки MoveFileW при условии, что источник и назначение находятся на одном устройстве (что может быть организовано), а файловая система - NTFS (что часто имеет место) - атомарная *.

Я бы позаботился о том, чтобы источник и место назначения находились на одном устройстве, чтобы переименование Linux не завершилось ошибкой, а переименование Windows на самом деле атомарное. Как упоминал Дэйв С выше, создание вашего временного файла (обычно с использованием ioutil.TempFile) в том же каталоге, что и существующий файл - это путь; Вот как я делаю мои атомные переименования.

Это работает для меня в моем случае использования, который:

  1. Процесс One Go получает обновления и переименовывает файлы для обмена обновлениями.
  2. Другой процесс Go отслеживает обновления файлов с помощью fsnotify и повторно отображает файл при его обновлении.

В приведенном выше случае использования просто с помощью os.Rename отлично сработал для меня.

Некоторое дальнейшее чтение:

  1. Является ли rename() атомарным? "Да и нет. Rename () является атомарным, если ОС не падает...."
  2. Возможно ли переименование атомарного файла (с перезаписью) в Windows?

* Примечание: я хочу отметить, что, когда люди говорят о файловых операциях атомарной файловой системы, с точки зрения приложения, они обычно подразумевают, что операция происходит или не происходит (с чем может помочь журналирование) с точки зрения пользователей. Если вы используете atomic в смысле операции атомарной памяти, очень немногие операции файловой системы (за исключением прямого ввода-вывода [ O_DIRECT ], который один блок записывает и читает с отключенной буферизацией диска) можно считать действительно атомарными.

Другие вопросы по тегам