首页 > 解决方案 > 将 ASCII 文件转换为二进制文件 - 高效的方法

问题描述

我正在尝试将 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 字符串转换为二进制时,究竟会发生什么?

标签: delphibinaryasciidelphi-7binaryfiles

解决方案


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)。

另请注意,无类型文件的使用效率不高(快速)。您应该使用基于 Stream 的文件函数,例如在 Method2 中。使用 TFileStream 或者 - 如果从文件中读取/写入多个小块数据则更好 - TBufferedFileStream 而不是 TStream,它是一个没有任何支持数据的流,即没有文件或内存与之关联,因此它不能直接使用。


推荐阅读