Почему TFileStream.write создает неверные данные? Dephi 7

Я попытался создать функцию / метод, который должен записывать в файл с заголовком: = StringOfChar (char (0), 11 * offsetSize); заполненный нулями

C026A200160000000100000006000000264C656B63650000B2000000B04D45005C1EA200306CA20000000000

Но когда я проверяю созданный файл, он имеет следующие значения (hex):

0000 0000 0000 0000 0000 0000

Я ожидал, что выходной файл должен содержать

chr(1)

Затем я также попытался заполнить его, C026A200160000000100000006000000264C656B63650000B2000000B04D45005C1EA200306CA20000000000 и результат был аналогичным:

#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0

(Это выглядит так же).

Когда я отлаживаю Delphi 7, я смотрю chr (1), когда он заполняется нулями:

#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1

Когда я заполняю его unit Dictionary_io; interface uses Classes, Windows, SysUtils, Dialogs; const offsetTableEntriesCount = 10; type TCountType = dword; TOffsetType = dword; TTextType = ANSIString; const testItemsCount = 1; type Dictionary = class private fsInput, fsOutput: TFileStream; fileName: string; msOffsets: TMemoryStream; offsetSize: TOffsetType; ofsTableEntries: TCountType; lng: integer; itemsCount: byte; header: TTextType; public constructor Create; procedure dicRewrite; end; implementation constructor Dictionary.Create; begin offsetSize := sizeof(offsetSize); end; procedure Dictionary.dicRewrite; var i: integer; begin itemsCount := 0; header := StringOfChar(char(0), 11*offsetSize); try fileName := 'A: est.bin'; if FileExists(fileName) then DeleteFile(fileName); fsOutput := TFileStream.Create(fileName, fmCreate); try fsOutput.Write(header,Length(header)); finally end; finally fsOutput.Free; end; end; end. потом, он содержит ...

header

Поэтому мой вопрос: почему это происходит? Что я делаю неправильно, что выходной файл содержит неправильные данные?

Write()

delphi,filestreams,tfilestream,

1

Ответов: 1


8 принят

Причина ваши данные не записываются в файл правильно, потому что вы не прохождения , Write()чтобы varправильно. headerпринимает нетипизированный Write()вход, и вы передаете ему headerпеременную as-is, поэтому вы сами передаете headerадрес памяти header. Но a stringсодержит указатель на символьные данные, которые хранятся в другом месте в памяти. Итак, чтобы записать эти данные в ваш файл, вам нужно разыменовать stringуказатель, чтобы вместо этого передать адрес памяти символьных данных.

Кроме того, если вы не хотите проверять возвращаемое значение Write()для ошибок, вы должны использовать WriteBuffer()вместо этого.

Попробуй это:

procedure Dictionary.dicRewrite;
var
  i: integer;
begin
  itemsCount := 0;
  header := StringOfChar(#0, 11*offsetSize);
  fileName := 'A:	est.bin';
  fsOutput := TFileStream.Create(fileName, fmCreate);
  try
    fsOutput.WriteBuffer(header[1], Length(header));
  finally
    fsOutput.Free;
  end;
end;

Или:

procedure Dictionary.dicRewrite;
var
  i: integer;
begin
  itemsCount := 0;
  header := StringOfChar(#0, 11*offsetSize);
  fileName := 'A:	est.bin';
  fsOutput := TFileStream.Create(fileName, fmCreate);
  try
    fsOutput.WriteBuffer(PAnsiChar(header)^, Length(header));
  finally
    fsOutput.Free;
  end;
end;

При этом вы действительно не должны использовать stringдвоичные данные (особенно если вы планируете обновить свой проект до Delphi 2009+. recordВместо этого вы должны использовать массив или массив, например:

private
  header: array of Byte;

procedure Dictionary.dicRewrite;
var
  i: integer;
begin
  itemsCount := 0;
  SetLength(header, 11*offsetSize);
  FillChar(header[0], Length(header), #0);
  fileName := 'A:	est.bin';
  fsOutput := TFileStream.Create(fileName, fmCreate);
  try
    fsOutput.WriteBuffer(header[0], Length(header));
  finally
    fsOutput.Free;
  end;
end;

Или:

procedure Dictionary.dicRewrite;
var
  i: integer;
begin
  itemsCount := 0;
  SetLength(header, 11*offsetSize);
  FillChar(PByte(header)^, Length(header), #0);
  fileName := 'A:	est.bin';
  fsOutput := TFileStream.Create(fileName, fmCreate);
  try
    fsOutput.WriteBuffer(PByte(header)^, Length(header));
  finally
    fsOutput.Free;
  end;
end;

Или:

private
  header: array[0..(11*offsetSize)-1] of Byte;

procedure Dictionary.dicRewrite;
var
  i: integer;
begin
  itemsCount := 0;
  FillChar(header, Length(header), #0);
  fileName := 'A:	est.bin';
  fsOutput := TFileStream.Create(fileName, fmCreate);
  try
    fsOutput.WriteBuffer(header, SizeOf(header));
  finally
    fsOutput.Free;
  end;
end;
Дельфы, потоковое видео, TFileStream,
Похожие вопросы