delphi - 将 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 字符串转换为二进制时,究竟会发生什么?
解决方案
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,它是一个没有任何支持数据的流,即没有文件或内存与之关联,因此它不能直接使用。
推荐阅读
- javascript - 如何从远程查询json服务器
- php - PHP MySql查询根据订单号返回订单的所有项目
- symfony - 许多实体关系之一
- c# - 尝试通过两个不同的选项卡登录时出现 AntiforgeryValidationException
- unit-testing - 如何在 Mockito 中模拟具有不同参数的方法的不同响应
- c# - 如何使用 linq 在 where 子句中设置条件过滤器?
- netsuite - 在 NetSuite SuiteScript 2.0 中检索已应用付款的相关发票
- git - 将 master 拉到 Intellij 的另一个分支上
- sql - 获取数据集作为另一个表的标题
- c++ - 在x64应用程序c ++中访问LDT寄存器