performance - Delphi 中的文本文件写入性能

标签 performance delphi file-io delphi-xe2

我的程序正在处理传入的字符串(来自 Telnet、HTTP 等),我必须使用 Delphi XE2 将这些字符串写入文本文件以用于记录目的。

有时程序可能会崩溃,我需要确保剩余的字符串不会丢失,因此我为每个传入的字符串打开/关闭文件,并且遇到一些性能问题。例如,下面的代码需要 8 秒才能完成。

我的代码如下,有什么方法可以提高性能吗?

(对于下面的测试,只需创建一个带有 Button : Button1OnClick 事件和 Label : lbl1 的表单)。

Procedure AddToFile(Source: string; FileName :String);
var
  FText : Text;
  TmpBuf: array[word] of byte;
Begin
  {$I-}
  AssignFile(FText, FileName);
  Append(FText);
  SetTextBuf(FText, TmpBuf);
  Writeln(FText, Source);
  CloseFile(FText);
  {$I+}
end;

procedure initF(FileName : string);
Var  FText : text;
begin
  {$I-}
  if FileExists(FileName) then  DeleteFile(FileName);
  AssignFile(FText, FileName);
  ReWrite(FText);
  CloseFile(FText);
  {$I+}
end;

procedure TForm1.Button1Click(Sender: TObject);
var tTime : TDateTime;
    iBcl : Integer;
    FileName : string;
begin
  FileName := 'c:\Test.txt';
  lbl1.Caption := 'Go->' + FileName; lbl1.Refresh;
  initF(FileName);
  tTime := Now;
  For iBcl := 0 to 2000 do
    AddToFile(IntToStr(ibcl) + '   ' +  'lkjlkjlkjlkjlkjlkjlkj' , FileName);
  lbl1.Caption  :=  FormatDateTime('sss:zzz',Now-tTime);
end;

最佳答案

使用 TStreamWriter ,它是自动缓冲的,并且可以自动将其缓冲区刷新到TFileStream。它还允许您根据需要选择附加到现有文件,设置 Unicode 支持的字符编码,并允许您在其各种重载 Create 中设置不同的缓冲区大小(默认为 1024 字节或 1K)。构造函数。

(请注意,刷新 TStreamWriter 只会将 TStreamBuffer 的内容写入 TFileStream;它不会刷新操作系统文件系统缓冲区,因此在释放 TFileStream 之前,文件实际上不会写入磁盘。)

不要每次都创建StreamWriter;只需创建并打开一次,最后关闭它:

function InitLog(const FileName: string): TStreamWriter;
begin
  Result := TStreamWriter.Create(FileName, True);
  Result.AutoFlush := True;         // Flush automatically after write
  Result.NewLine := sLineBreak;     // Use system line breaks
end;

procedure CloseLog(const StreamWriter: TStreamWriter);
begin
  StreamWriter.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var 
  tTime : TDateTime;
  iBcl : Integer;
  LogSW: TStreamWriter;
  FileName: TFileName;
begin
  FileName := 'c:\Test.txt';
  LogSW := InitLog(FileName);
  try
    lbl1.Caption := 'Go->' + FileName; 
    lbl1.Refresh;
    tTime := Now;

    For iBcl := 0 to 2000 do
      LogSW.WriteLine(IntToStr(ibcl) + '   ' +  'lkjlkjlkjlkjlkjlkjlkj');

    lbl1.Caption  :=  FormatDateTime('sss:zzz',Now - tTime);
  finally
    CloseLog(LogSW);
  end;
end;

关于performance - Delphi 中的文本文件写入性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13306752/

相关文章:

c++ - __forceinline 的执行速度是否比 __inline 快?

sql-server - TSQL - 检查多条记录的最快方法是什么?

performance - 递归与手动堆栈 - 在哪种情况下首选?

delphi - DataSnap 服务器 - 将 HTTP 请求重定向到另一个 DataSnap 服务器

c# - 检查正在运行的特定进程的快速方法

file-io - 读取一个golang文件并用大写字母替换单词搜索

bash 根据日期创建文件?

F#中懒惰的表现

delphi - Delphi XE8 中的数字分区算法生成器

javascript - 代码在 jsFiddle 上运行良好但在本地系统上运行不正常