将ASCII文件转换为二进制文件 - 高效方法

时间:2018-06-04 02:57:32

标签: delphi binary ascii delphi-7 binaryfiles

我正在尝试将ASCII文件转换为二进制文件。这是一个集成,他们期待我的二进制文件。 我尝试了很少的东西来实现同样的目标。

方法1

function TForm1.ReadString(var fd: File): string;
var
  count: Cardinal;
  l: integer;
begin
  BlockRead(fd,l,SizeOf(integer),count);
  SetLength(Result,l);
  BlockRead(fd,Result[1],l,count);
end;

procedure TForm1.WriteString(var fd: File; str: string);
var
  count: Cardinal;
  l: integer;
begin
  l := Length(str);
  BlockWrite(fd,l,SizeOf(integer),count);
  BlockWrite(fd,str[1],l,count);
end;

使用上述方法我无法取回原始字符串以验证其是否正常工作。

所以尝试了另一种方法:

方法2

procedure TForm1.convertobinary2;
var
  lFS: TFileStream;
  lBuf: TBytes;
  lFullFileName: string;
  SourceFile: Tstringlist;
  StreamData: TStream;
begin

  lFullFileName := ExtractFilePath(Application.ExeName) + 'Binary.txt';
  SourceFile := Tstringlist.Create;
  SourceFile.LoadFromFile('D:\Text File');

  StreamData := TStream.Create;

  StringToStream(StreamData, SourceFile.Text);

  lFS := TFileStream.Create(lFullFileName, fmCreate);
  try
    SetLength(lBuf, StreamData.Size);
    StreamData.Position := 0;
    StreamData.ReadBuffer(lBuf[0], StreamData.Size);

    lFS.WriteBuffer(lBuf[0], StreamData.Size);
  finally
    lFS.Free;
    FreeandNil(SourceFile);
    FreeandNil(StreamData);
  end;
end;

这里我在尝试ReadBuffer时遇到异常。

 Exception class EStreamError with message 'TStream.Seek not implemented'

如果有人能指出我正确的方向,我真的很感激。 a)这是将ASCII文件转换为二进制文件的有效方法。 b)当我们尝试将ASCII字符串转换为二进制时会发生什么。

1 个答案:

答案 0 :(得分:1)

function TForm1.ReadString(var fd: File): string;
var
  count: Cardinal;
  l: integer;
  {$ifdef UNICODE }
    u8: Utf8String;
  {$endif }
begin
  BlockRead(fd,l,SizeOf(integer),count);
  {$ifdef UNICODE }
    SetLength(u8,l);
    if l>0 then BlockRead(fd,u8[1],l,count);
    Result:=u8;
  {$else }
    SetLength(Result,l);
    if l>0 then BlockRead(fd,Result[1],l,count);
  {$endif }
end;

procedure TForm1.WriteString(var fd: File; const str: string);
var
  count: Cardinal;
  l: integer;
  {$ifdef UNICODE }
    u8: UTF8String;
  {$endif }
begin
  {$ifdef UNICODE }
    u8 := str;
    l := Length(u8);
    BlockWrite(fd,l,SizeOf(integer),count);
    if l>0 then BlockWrite(fd,u8[1],l,count);
  {$else }
    l := Length(str);
    BlockWrite(fd,l,SizeOf(integer),count);
    if l>0 then BlockWrite(fd,str[1],l,count);
  {$endif }
end;

以上函数适用于编译器的UNICODE和ANSI版本。但请注意,编译的不同版本(UNICODE / ANSI)之间的数据不兼容。编译器的UNICODE版本创建的文件无法通过ANSI版本的编译器读取(无需一些修改),反之亦然。

另请注意,保存到文件的数据在ANSI版本的编译器中是ANSI,在UNICODE版本的编译器中是UTF-8(8位UNICODE)。

程序的接口在两个实例中都是编译器的本机STRING类型(ANSI编译器中的AnsiString,UNICODE编译器中的UnicodeString)。

另请注意,无类型文件的使用效率(速度方面)效率不高。您应该使用类似于Method2中的基于流的文件函数。使用TFileStream或 - 如果从文件中读取/写入多个小块数据 - 更好 - TBufferedFileStream而不是TStream,这是一个没有任何后备数据的流,即。没有文件或内存与之关联,因此无法直接使用。