Delphi 如何写入正在读取的文件?

Delphi 如何写入正在读取的文件?,delphi,file-io,Delphi,File Io,我的应用程序缓慢地读取浮点数字的文本文件。环境有时会发生变化,文件必须重写。一些示例代码: procedure TAMI_Column_Selector.read_continuously (file_name: string); var infile: TextFile; f: Double; begin AssignFile (infile, file_name); Reset (infile); try while not EOF (infile) d

我的应用程序缓慢地读取浮点数字的文本文件。环境有时会发生变化,文件必须重写。一些示例代码:

procedure TAMI_Column_Selector.read_continuously (file_name: string);
var infile: TextFile;
    f: Double;
begin
   AssignFile (infile, file_name);
   Reset (infile);
   try
      while not EOF (infile) do
      begin
         Read (infile, f);
         process (f); // this may take quite some time, seconds or even minutes
      end; // while
   finally
      CloseFile (infile);
   end; // try..finally
end; // read_continuously //
如何编写一个打开阅读的文件?更具体地说:

  • 如何编写一个打开阅读的文件
  • 当应用程序试图读取一个文件时,如何防止崩溃 正在编写
  • 我的应用程序如何知道文件已被重写
  • 我想我可以解决第一个问题,将文件读入内存并读取(是否有一个文本文件可以写入内存并从内存读取)?然后仍然是我如何测试一个文件已经写过了

    有人对这个问题有(优雅的)解决方案吗

    提前谢谢


    在windows 7上使用Delphi XE来写入一个也可以打开阅读的文件,通常编写者不需要做任何特殊的事情。如果打开该文件的其他所有人都允许写入该文件,则目标写入者可以打开该文件进行写入、写入该文件,然后关闭该文件。如果其他人不允许写入该文件,那么首先将不允许指定的编写器打开该文件,并且它对此无能为力

    如何打开文件进行读取,同时允许写入取决于所使用的打开方法。对于
    CreateFile
    ,dwDesiredAccess参数是通常的
    GENERIC\u READ
    ,而dwShareMode参数是
    FILE\u SHARE\u READ或FILE\u SHARE\u WRITE
    。如果使用的是
    TFileStream
    ,则构造函数的模式参数应为
    fmOpenWrite或fmsharedynone
    。如果使用的是
    AssignFile
    Reset
    ,则需要设置
    FileMode
    全局变量,但该变量不支持任何共享模式,因此不能使用Pascal样式的I/O

    读取正在写入的文件本身不会导致崩溃。它当然不会在操作系统级别引起问题。如果你的程序崩溃了,那是因为它不是为了预测阅读失败而编写的。当您读取某些内容时,请检查API结果以确认您读取的字节数与您请求的字节数相同。您还可以让读写应用程序相互通信。您可以使用同步对象序列化对文件的访问,或者编写器可能会向读取器发送一个信号,指示文件已更改,并且以前的读取可能不再准确。细节由你决定

    如果读取器要在内存中保留文件的副本,那么它可能不需要麻烦共享写访问权限。相反,它可以打开文件并仅共享读取权限,在内存中复制文件,然后关闭文件。然后,编写器可以打开文件,而不必担心会破坏读卡器进程,因为没有什么可以破坏的。它可以通知读卡器有更改,读卡器可以重新加载整个文件,也可以只加载更改的部分。(不过,编写器必须告诉读者哪一部分发生了更改;如果读者不读取整个文件并查看它与内存副本的差异,就没有其他方法可以检测到这一点。)


    防止写操作干扰读操作的另一种方法是使用事务。不过,这项技术正在逐步淘汰。Microsoft已发布,因此您可以尝试查找符合您需要的内容。

    使您的阅读程序对不完整的阅读具有鲁棒性。然后使用现代IO(即
    TFileStream
    )而不是Pascal IO。对于写入程序,请在打开文件时指定
    fmShareDenyWrite
    。为您的阅读器指定
    fmsharedynone
    。或者,使用数据库!我描述的情况是一个导入工具,所以我使用csv文件。一个数据库可以解决所有问题,但在这种情况下是不可行的。非常感谢您详细的回答。我认为它解决了我应该避免的所有陷阱。有一件事我还不知道,我怎么知道文件已经(重新)写了呢?我应该更准确地表达问题3。我的意思是如何检测另一个应用程序正在修改的文件。我认为第3段解释了如何在解释中发现变化。如果有更多的打算,我不知道该怎么办。这一直是我的假设:一个或多个进程正在阅读,另一个或多个进程正在写作。让一个进程知道另一个进程修改了文件的可靠方法是让另一个进程告诉它它已经修改了文件;这就是我第三段第二部分的意思。您还可以尝试使用检测目录中的文件大小或上次写入时间是否已更改。非常感谢!你的回答让我从使用文本文件改为使用流。这样可以更好地控制打开文件的模式。关于“ReadDirectoryChangesW”的一个问题是:在编写文件时,它会多次触发:有没有办法确定哪个事件属于关闭事件?另见