Конвертировать файл ASCII в двоичный файл - эффективные методы - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь преобразовать файл ASCII в двоичный файл.Это для интеграции, где они ожидают от меня двоичного файла.

Я попробовал несколько вещей, чтобы добиться того же.

Method1

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;

Используя вышеуказанные методы, я не могу вернуть исходную строку, чтобы проверить, работает ли она нормально.

Итак, попробовал другой метод:

Method2

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 в двоичный файл?б) Что именно происходит, когда мы пытаемся преобразовать строку ASCII в двоичный файл?

1 Ответ

0 голосов
/ 04 июня 2018
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) компиляции.Файл, созданный версией компилятора в Юникоде, не может быть прочитан (без каких-либо изменений) версией компилятора ANSI или наоборот.

Также обратите внимание, что данные, сохраненные в файле, являются ANSI вANSI-версии компилятора и UTF-8 (8-битный Unicode) в Unicode-версиях компилятора.

Интерфейс к программе в обоих случаях является родным типом компилятора STRING (AnsiString в компиляторах ANSI,UnicodeString в компиляторах Unicode).

Также обратите внимание, что нетипизированные файлы не эффективны (по скорости) для использования.Вы должны использовать потоковые файловые функции, как в вашем Method2.Используйте TFileStream или, что еще лучше, если из файла записываются / записываются в файл несколько небольших фрагментов, - TBufferedFileStream, а не TStream, который является потоком без каких-либо данных поддержки, т. Е. С ним не связан ни один файл или память, и, следовательно, он не может бытьиспользуется напрямую.

...