1

当应用程序保存文件时,典型的模型是将文件保存到临时位置,然后将临时文件移动到最终位置。在某些情况下,“移动”变成了“替换”。在伪代码中:

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 文件的同时做首选的事情,该文件首先保存到临时目录然后移动到最终目录?

4

9 回答 9

1

Microsoft Word 将临时文件保存到以波浪号 (~) 开头的原始目录。我会遵循那个约定。

于 2009-07-15T00:26:09.653 回答
1

如果它只是一个临时文件,请在 temp 文件夹中创建一个临时文件。否则,在其最终目的地创建它。

注意事项:

1)如果最终目的地是“拾取”文件夹,这可能不起作用(除非“拾取”过程检查锁定的文件(它应该))

2) 最终目的地具有特殊权限,必须在代码中创建并应用才能移动到最终目的地。

于 2009-07-15T00:27:01.933 回答
1

如果这些临时文件会变成永久文件,请在同一位置创建它们以避免必须跨磁盘/分区“移动”文件的任何风险,这将导致更多 I/O(作为副本然后删除) .

如果这些是真正临时的临时文件,请在临时目录中创建(并保留它们)。

于 2009-07-15T03:11:45.283 回答
1
  1. 最好使用 GetTempFile 例程创建临时文件,因为这会在预定义的位置(例如 C:\temp)创建临时文件,如果您的应用程序崩溃或在其中生成损坏的文件,实用程序可以删除这些临时文件。如果在您的最终目录中发生同样的事情, 是不可恢复的。

  2. 是的,如果目标文件的属性或 ACL 已被编辑,属性可能会有所不同。即使您在同一文件夹中创建临时文件,也可能发生这种情况。

  3. 您可以通过使用 File.Replace 例程来解决此问题,该例程执行一个文件与另一个文件的原子替换,将新文件的属性和 ACL 替换为旧文件的属性。

执行此操作的 AC# 方法是对文件安全流更新的回答。

于 2009-07-15T03:27:37.140 回答
1

您可能不想将文件写入一个目录并将其移动到另一个目录的原因是因为这些目录可能位于不同的文件系统上。尽管这在 Windows 上不太常见,但只要父文件系统是 ntfs,它仍然是合理的。在 unix 中,将 /tmp 设置为不同的文件系统是一种标准做法。

这可能是一个问题的原因是因为这意味着必须将文件从一个地方复制到另一个地方。这会显着影响大文件的性能,并且肯定需要更多的搜索,即使文件很小。此外,在跨文件系统边界移动文件时,还有更多方法会导致此操作失败。当然,访问权限可能不同,但目标文件系统也可能已满,或者您现在推迟到很久以后的任何其他额外复杂性。

于 2009-07-15T03:34:21.010 回答
0

我更喜欢将临时文件保存到最终目录:

  1. 它避免了您描述的潜在权限问题。

  2. 最终目录可能位于不同的卷上,在这种情况下(将临时文件移动到最终文件)实际上是复制 + 删除 - 如果您经常这样做或文件很大,则会产生很多开销。

您始终可以将现有文件重命名为第二个临时文件,将新临时文件重命名为现有文件的名称,并在出错时回滚。在我看来,这似乎是最安全的组合。

编辑:我看到你的“停车场”已经描述了我的建议,所以我不确定我在这里添加了多少。

于 2009-07-15T00:26:03.833 回答
0

1. 是的,最好先保存到临时文件

因为如果文件创建因任何原因失败,最终文件将永远不会处于损坏状态。如果您直接写入最终文件并且您的程序在中途崩溃......它肯定会使最终文件处于无效状态。

2. 是的

“继承的”属性和权限当然会有所不同。但是大多数系统上的临时目录通常是预先配置的,供所有应用程序使用。但是,可能需要配置“最终文件”目录。例如,说“程序文件”文件夹和 Vista UAC。

3. 在替换之前将 ACL 从最终文件复制到临时文件?

于 2009-07-15T00:29:25.863 回答
0

默认情况下,当 File.createTempFile() 中的后缀参数设置为 null 时,Android 会将 .tmp 作为后缀。我建议你就用那个。

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

在您的应用程序中处理完 .tmp 文件后,您应该自己调用 file.delete()。您不应该依赖 file.deleteOnExit() 因为绝对不能保证它会被 Android 系统/VM 使用。

于 2012-05-16T13:17:05.560 回答
-1

为什么不让它用户可配置?一些用户不喜欢临时文件污染他们当前的目录。

于 2009-07-15T00:49:38.210 回答