Лучший способ атомарного создания файлов - PullRequest
1 голос
/ 24 августа 2009

«Лучшая практика» (как я ее вижу) для атомарного создания нового файла - это открыть временный файл (используя tmpfile () ), а затем переместить файл в его окончательное местоположение.

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

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

Существует ли метод, аналогичный tmpfile (), который позволит мне указать точку монтирования? Я понимаю, что это, вероятно, не существует встроенного в PHP, поэтому также допустима функция Posix / C или вызов оболочки.

Ответы [ 4 ]

2 голосов
/ 24 августа 2009

Нет, такого метода нет в стеке POSIX. tmpfile () и tmpname () используют для обычного временного каталога. Существует tempnam () , где вы можете указать целевой каталог для временного файла. Но это в основном способ реализации второго варианта, который вы описали.

1 голос
/ 26 августа 2009

Протокол maildir , разработанный для qmail, обеспечивает безопасное создание файлов для нескольких устройств записи в один и тот же целевой каталог, даже через NFS. В этой схеме каталог «tempfile» гарантированно находится в той же файловой системе, что и целевой каталог.

Алгоритм удобно реализован в эффективной утилите оболочки, safecat, справочная страница которой представляет алгоритм как:

safecat применяет алгоритм maildir, записывая данные в шесть шагов. Во-первых, это stat () - две директории tempdir и destdir и выход если оба каталога не существуют и доступны для записи. Во-вторых, это stat () имя tempdir / time.pid.host, где время - количество секунд с начало 1970 по Гринвичу, pid - это идентификатор процесса программы, а host - имя хоста. В-третьих, если stat () вернул что-либо кроме ENOENT, программа спит две секунды, обновляет время и пробует stat () опять же, ограниченное количество раз. В-четвертых, программа создает TEMPDIR / time.pid.host. В-пятых, программа NFS-пишет сообщение в файл. В-шестых, программа () ссылается на файл в destdir / time.pid.host. В в этот момент данные были успешно записаны.

Кроме того, safecat запускает 24-часовой таймер перед созданием tempdir / time.pid.host и прерывает запись, если таймер истекает. на ошибка, тайм-аут или нормальное завершение, safecat пытается отменить () TEMPDIR / time.pid.host.

0 голосов
/ 24 августа 2009

Я должен был сделать что-то вроде этого и пошел с БД MySQL. Просто сохранил нужную мне информацию в таблице, и когда я закончил, я просто удалил запись. Просто мысль:)

0 голосов
/ 24 августа 2009

Поскольку вы говорите о "точке монтирования", я предполагаю, что вы находитесь в среде, подобной Unix.

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

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

...