替换文件中的字符(更快的方法)

Sha*_*ane 3 delphi ascii replace file

我们经常用另一个"好"字符替换文件中的非理想字符.

界面是:

procedure cleanfileASCII2(vfilename: string; vgood: integer; voutfilename: string);
Run Code Online (Sandbox Code Playgroud)

用我们可能调用的空格替换所有非desirables,cleanfileASCII2(original.txt,32,cleaning.txt)

问题是这需要相当长的时间.有没有比展示更好的方法呢?

procedure cleanfileASCII2(vfilename: string; vgood: integer; voutfilename:
string);
var
  F1, F2: file of char;
  Ch: Char;
  tempfilename: string;
  i,n,dex: integer;
begin
   //original
    AssignFile(F1, vfilename);
    Reset(F1);
    //outputfile
    AssignFile(F2,voutfilename);
    Rewrite(F2);
      while not Eof(F1) do
      begin
        Read(F1, Ch);
        //
          n:=ord(ch);
          if ((n<32)or(n>127))and (not(n in [10,13])) then
             begin // bad char
               if vgood<> -1 then
                begin
                ch:=chr(vgood);
                Write(F2, Ch);
                end
             end
           else   //good char
            Write(F2, Ch);
      end;
    CloseFile(F2);
    CloseFile(F1);
end;
Run Code Online (Sandbox Code Playgroud)

小智 6

问题与你如何处理缓冲区有关.内存传输是任何操作中最昂贵的部分.在这种情况下,您将逐字节查看文件.通过更改为块读或缓冲读取,您将实现速度的大幅提升.请注意,正确的缓冲区大小取决于您所在的位置.对于网络文件,由于TCP/IP数据包大小的限制,您会发现极大的缓冲区可能效率较低.即使这对于gigE的大包也变得有点模糊,但是,一如既往,最好的结果就是对它进行基准测试.

为方便起见,我将标准读取转换为文件流.你可以用blockread轻松做同样的事情.在这种情况下,我拿了一个15MB的文件并在你的例行程序中运行它.在本地文件上执行操作需要131,478ms.使用1024缓冲区,花了258ms.

procedure cleanfileASCII3(vfilename: string; vgood: integer; voutfilename:string);
const bufsize=1023;
var
  inFS, outFS:TFileStream;
  buffer: array[0..bufsize] of byte;
  readSize:integer;
  tempfilename: string;
  i: integer;
begin
   if not FileExists(vFileName) then exit;

   inFS:=TFileStream.Create(vFileName,fmOpenRead);
   inFS.Position:=0;
   outFS:=TFileStream.Create(vOutFileName,fmCreate);
   while not (inFS.Position>=inFS.Size) do
      begin
      readSize:=inFS.Read(buffer,sizeof(buffer));
      for I := 0 to readSize-1 do
          begin
          n:=buffer[i];
          if ((n<32)or(n>127)) and (not(n in [10,13])) and (vgood<>-1) then
             buffer[i]:=vgood;
          end;
      outFS.Write(buffer,readSize);
      end;
   inFS.Free;
   outFS.Free;
end;
Run Code Online (Sandbox Code Playgroud)