【问题标题】:What could cause an unexpected 'File In Use' Error什么可能导致意外的“正在使用的文件”错误
【发布时间】:2014-09-22 15:35:25
【问题描述】:

我有一个 Delphi5 应用程序,它将文件 (.pdf) 和一个非常小的元数据文件导出到网络位置。目的是轮询 .NET 应用程序应处理这两个文件,然后将其删除。

我的方法是

  1. 使用扩展名“.part”编写元数据文件
  2. 生成 .pdf
  3. 将 .part 文件重命名为 .dat

.NET 进程只查找扩展名为“.dat”的文件,因此我希望这两个读取器/写入器之间不会发生冲突。但是,.NET 进程偶尔会记录以下错误...

System.IO.IOException: The process cannot access the file '\\server\Path\FileName.dat' because it is being used by another process.

(我偶尔会说 - 我们目前正在测试,所以当数量增加时,这可能会成为一个更大的问题)

Delphi 代码如下所示:

AssignFile(FTextFile, Format('%s\%s.part', [DMSPath, FullFileName])); 
try
  try
    ReWrite(FTextFile);
    Writeln(FTextFile, MetaDataString);
  finally  
    CloseFile(FTextFile);
  end;
except
  raise ELogFileException.Create( LOGFILEWRITEFAILURE );
end;

然后有一个单独的方法执行以下代码行

if FindFirst(Format('%s\*.part',[DMSPath]), faAnyFile, SearchRec) = 0 then begin
  repeat
    OldName := Format('%s\%s',[DMSPath, SearchRec.Name]);
    NewName := Format('%s\%s',[DMSPath, ChangeFileExt(SearchRec.Name, '.dat')]);
    RenameFile(OldName, NewName);
  until FindNext(SearchRec) <> 0;
  FindClose(SearchRec);
end;

我看不出这段代码有什么本质上的错误,我们有一些补救措施,但我有 2 个问题

  1. 我是否应该尝试一种不同的技术来更可靠地保护“.dat”文件直到它完全准备好
  2. 什么情况会导致这种情况?

到目前为止,有一个建议的原因 - 防病毒软件。

关于如何以不同方式生成文件有什么建议吗?注意我的应用是Delphi5;我想知道是否有我可以使用的“MoveFileA”WinApi 调用的更新、更“原子”版本。

【问题讨论】:

  • 常见原因是您的 AV 软件
  • 谢谢,@David - 我没想到
  • Windows Search 曾经导致这个问题,虽然我最近没有看到它,所以它现在可能已修复。如果这是原因,您可以通过在您创建的文件上设置“不索引”属性来解决它。
  • When in doubt, run Process Monitor。说真的:运行 procmon,设置一些过滤,等待异常发生并查看其他进程正在使用您的 .dat 文件。
  • @Lieven - 很好的提示,谢谢。

标签: delphi winapi file-io delphi-5


【解决方案1】:

过去,我们遇到过文件被这样锁定的问题。调查指向 Windows 的 Prefetch。但受影响的文件不在网络目录中。

据我所知,Prefetch 仅适用于进程启动和/或启动时(由注册表项控制),因此它可能不适用于您当前的情况。

您可以查看“C:\"Windows"\Prefetch\" 目录。如果预取是活动的,它应该包含多个 *.pf 文件。如果有一个与您的可执行文件名相同,则可能值得调查。

【讨论】:

    【解决方案2】:

    就个人而言,因为涉及多个文件,我会创建一个单独的锁定文件(例如,myfile.lck),您首先编写。如果轮询应用程序在文件夹中看到它,则它会停止寻找其他文件。一旦该文件消失,它就会更深入。我不知道这是否可以解决您遇到的问题,但我会尝试一下。 (带有 .dat 扩展名的文件经常由恶意作恶者创建,因此它们可能会通过其他来源(如 AV 软件)引发虚假问题。其中包含 0 字节的锁定文件通常是无害的且被忽略。)

    【讨论】:

    • 那不是耽误了问题吗?即使消费者应用程序更改为首先查找锁定文件,它仍然需要读取 dat 文件,因此仍然有可能会使用 dat。当消费者应用程序说文件仍在被另一个进程使用时,我们不知道那是什么进程。我认为您假设它是生产者应用程序。无论哪种方式,生产者在重命名之前已经关闭了 dat 文件。
    • 不要相信我的话。这就是 Unix/Linux 系统一直以来的做法。从根本上说,您指的是并发问题。您需要使用某种标志。文件创建操作通常被认为是原子的。您将获得一个返回代码,说明该文件已创建,或者一个错误代码说明该文件已存在。如果存在,则不要继续。如果您创建了它,则可以安全地继续。完成后请务必将其删除。
    • 显然,如果有其他应用程序不遵循此协议并访问其他文件,这将不起作用。同样,.dat 文件经常由恶意软件创建,所以我不知道如果它是您的 AV 软件,您是否可以做很多事情,除了进入并将文件标记为“安全”(如果可能的话)。
    猜你喜欢
    • 2020-11-26
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多