1

我试图创建一个函数/方法,该函数/方法应该写入一个标头填充零的文件

header := StringOfChar(char(0), 11*offsetSize);

但是当我检查创建的文件时,它具有以下值(十六进制):

C026A200160000000100000006000000264C656B63650000B2000000B04D45005C1EA200306CA20000000000

我希望输出文件应该包含

0000 0000 0000 0000 0000 0000

然后我也尝试用它来填充它,chr(1)结果是相似的:

C026A200160000000100000006000000264C656B63650000B2000000B04D45005C1EA200306CA20000000000

(看起来一样)。

当我在 Delphi 7 中进行调试时,我会在标题填充零时观察它:

#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

当我填充它时,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:\test.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.
4

1 回答 1

8

您的数据未正确写入文件的原因是您未正确传递headerto Write()Write()将无类型var作为输入,并且您将header变量按原样传递给它,因此您传递Write()的是自身的内存地址header。但是 astring包含一个指向存储在内存中其他地方的字符数据的指针。因此,为了将该数据写入文件,您需要取消对string指针的引用,以便传入字符数据的内存地址。

此外,如果您不想检查Write()错误的返回值,则应WriteBuffer()改为使用。

尝试这个:

procedure Dictionary.dicRewrite;
var
  i: integer;
begin
  itemsCount := 0;
  header := StringOfChar(#0, 11*offsetSize);
  fileName := 'A:\test.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:\test.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:\test.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:\test.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:\test.bin';
  fsOutput := TFileStream.Create(fileName, fmCreate);
  try
    fsOutput.WriteBuffer(header, SizeOf(header));
  finally
    fsOutput.Free;
  end;
end;
于 2018-07-07T20:53:05.747 回答