简体   繁体   English

Delphi-如何在保存之前删除非 ANSI(不可打印)字符?

[英]Delphi- How to remove NON ANSI (NOT PRINTABLE) characters before saving?

Can somebody guide me to extend this procedure in a way so it removes all Non Printable characters or replaces with SPACE before it saves the stream to file?有人可以指导我以某种方式扩展此过程,以便在将 stream 保存到文件之前删除所有不可打印字符或替换为空格吗? String is read from Binary and could be maximum of 1 MB size.字符串从二进制中读取,最大大小为 1 MB。 My Procedure:我的程序:

var
  i : Word;
  FileName : TFileName;
  SizeofFiles,posi : Integer;
  fs, sStream: TFileStream;
  SplitFileName: String;
begin
  ProgressBar1.Position := 0;
  FileName:= lblFilePath.Caption;
  SizeofFiles := StrToInt(edt2.Text)  ;
  posi := StrToInt(edt1.text) ;
  fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
             fs.Position := Posi ;
    begin
      SplitFileName := ChangeFileExt(FileName, '.'+ FormatFloat('000', i));
      sStream := TFileStream.Create(SplitFileName, fmCreate or fmShareExclusive);
      try
        if fs.Size - fs.Position < SizeofFiles then
          SizeofFiles := fs.Size - fs.Position;
        sStream.CopyFrom(fs, SizeofFiles);
        ProgressBar1.Position := Round((fs.Position / fs.Size) * 100);
      finally
        sStream.Free;
      end;
    end;
  finally
    fs.Free;
  end;
end;

You won't be able to use TStream.CopyFrom() anymore.您将无法再使用TStream.CopyFrom() You would have to Read(Buffer)() from the source TStream into a local byte array, strip off whatever you don't want from that array, and then Write(Buffer)() the remaining bytes to the destination TStream .您必须将源TStream中的Read(Buffer)()读取到本地字节数组中,从该数组中删除您不想要的任何内容,然后将剩余字节Write(Buffer)()到目标TStream

Here is a simple demo that should do what you want:这是一个简单的演示,应该可以满足您的要求:

const
    SrcFileName   : String = 'Test.txt';
    DstFileName   : String = 'TestResult.txt';
    StartPosition : Int64  = 50;

procedure TForm1.Button1Click(Sender: TObject);
var
    FS  : TFileStream;
    Buf : TBytes;
    I   : Integer;
begin
    // Read the source file from starting position
    FS := TFileStream.Create(SrcFileName, fmOpenRead or fmShareDenyWrite);
    try
        FS.Position := StartPosition;
        SetLength(Buf, FS.Size - FS.Position);
        FS.Read(Buf[0], Length(Buf));
    finally
        FreeAndNil(FS);
    end;

    // Replace all non printable character by a space
    // Assume file content is ASCII characters
    for I := 0 to Length(Buf) - 1 do begin
        // You may want to make a more complex test for printable of not
        if (Ord(Buf[I]) < Ord(' ')) or (Ord(Buf[I]) > 126) then
            Buf[I] := Ord(' ');
    end;

    // Write destination file
    FS := TFileStream.Create(DstFileName, fmCreate);
    try
        FS.Write(Buf[0], Length(Buf));
    finally
        FreeAndNil(FS);
    end;
end;

This code assume the file is pure ASCII text and that every character whose ASCII code is below 32 (space) or above 126 is not printable.此代码假定文件是纯 ASCII 文本,并且 ASCII 代码低于 32(空格)或高于 126 的每个字符都是不可打印的。 This may not be the case for European languages.欧洲语言可能并非如此。 You'll easily adapt the test to fit your needs.您可以轻松地调整测试以满足您的需求。

The source file could also be Unicode (16 bits characters).源文件也可以是 Unicode(16 位字符)。 You should use a buffer made of Unicode characters or 16 bit integers (Word).您应该使用由 Unicode 字符或 16 位整数(字)组成的缓冲区。 And adapt the test for printable.并调整可打印的测试。

Could also be UTF8...也可以是UTF8...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM