Должен ли я записать временный файл в временный каталог? или записать временный файл в окончательный каталог? - PullRequest
1 голос
/ 15 июля 2009

Когда приложение сохраняет файл, типичная модель - сохранить файл во временном местоположении, а затем переместить временный файл в конечное местоположение. В некоторых случаях этот «ход» становится «заменой». В псевдокоде:

Save temp file;
if final file exists
   delete final file;
move temp file to final filename;

Там есть окно, где удаление может быть успешным, но перемещение может и не быть, поэтому вы можете обработать это следующим образом:

Save temp file;
if final file exists
   move final file to parking lot
move temp file to final filename;
if move succeeded       
   delete previous final file. 
else
   restore previous final file. 

Теперь на мои вопросы:

  1. предпочтительно сохранить временный файл во временный каталог, а затем переместить его, в отличие от сохранения временного файла в последний каталог? (если так, то почему?)

  2. Есть ли разница в атрибутах и ​​разрешениях для файла, который сначала сохраняется во временном каталоге, а затем перемещается в конечный файл в другом каталоге по сравнению с файлом, который сохраняется во временном файле в итоговом каталоге , а затем переименовать в этом каталоге?

  3. Если ответы на оба вопроса - ДА, то как я могу сделать предпочтительную вещь, получая соответствующий ACL для файла, который сначала был сохранен во временный каталог, а затем перемещен в конечный каталог?

Ответы [ 9 ]

1 голос
/ 15 июля 2009

Причина, по которой вы, возможно, захотите никогда не записывать файл в один каталог и не перемещать его в другой, заключается в том, что эти каталоги могут находиться в разных файловых системах. Хотя это не так часто встречается в Windows, это все же возможно, если родительской файловой системой является ntfs. В Unix это стандартная практика для / tmp, чтобы быть другой файловой системой.

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

1 голос
/ 15 июля 2009

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

Если это временные файлы, которые действительно являются временными, создайте (и оставьте их) в временном каталоге.

1 голос
/ 15 июля 2009
  1. Желательно создать временный файл, используя подпрограммы GetTempFile, потому что это создает временные файлы в предопределенных местах (например, C: \ temp), которые утилиты могут удалять, если ваше приложение вылетает или создает поврежденные файлы. Если то же самое что-то происходит в вашем последнем каталоге, это невозможно исправить.

  2. Да, атрибуты могут отличаться, если атрибуты целевого файла или ACL были отредактированы. Это может произойти, даже если вы создадите временный файл в той же папке.

  3. Это можно исправить с помощью процедуры File.Replace, которая выполняет атомарную замену одного файла другим, заменяя атрибуты нового файла и ACL-списки старым файлом.

Метод C #, который делает это, является ответом на Безопасное обновление потока файла .

1 голос
/ 15 июля 2009

Создайте временный файл во временной папке, если это просто временный файл. В противном случае создайте его в конечном пункте назначения.

Предостережения:

1) Это может не работать, если конечным пунктом назначения является папка «раскладки» (если процесс «раскладки» не проверяет заблокированные файлы (что и должно быть))

2) Конечный пункт назначения имеет специальные разрешения, которые должны быть созданы в коде и применены перед возможностью перехода к конечному пункту назначения.

1 голос
/ 15 июля 2009

Microsoft Word сохраняет временный файл в исходный каталог, начиная с тильды (~). Я бы просто следовал этому соглашению.

0 голосов
/ 16 мая 2012

По умолчанию Android помещает .tmp в качестве суффикса, если для параметра суффикса в File.createTempFile () установлено значение null. Я бы посоветовал вам просто использовать это.

File file = File.createTempFile(imageFileName, null, storageDir);

Вы должны вызывать file.delete () самостоятельно, как только закончите с вашим файлом .tmp в своем приложении. Вы не должны зависеть от file.deleteOnExit (), поскольку нет абсолютно никаких гарантий, что он будет использоваться системой Android / VM.

0 голосов
/ 15 июля 2009

Почему бы не сделать его настраиваемым пользователем? Некоторым пользователям не нравятся временные файлы, загрязняющие их текущий каталог.

0 голосов
/ 15 июля 2009

1. Да, предпочтительно сначала сохранить во временный файл

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

2. Да

«Унаследованные» атрибуты и разрешения, конечно, будут разными. Но временные каталоги в большинстве систем обычно предварительно настроены для использования всеми приложениями. Однако каталог «конечный файл» может потребоваться настроить. Скажем, например, папка «Program Files» и Vista UAC.

3. Скопировать ACL из окончательного файла во временный файл перед заменой?

0 голосов
/ 15 июля 2009

Я предпочитаю сохранять временный файл в окончательный каталог:

  1. Это позволяет избежать потенциальных проблем с разрешениями, которые вы описали.

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

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

РЕДАКТИРОВАНИЕ : Я вижу, что ваша "стоянка" уже описала мое предложение, поэтому я не уверен, что многое добавил сюда.

...