首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么TFileStream.write产生不正确的数据?伤寒人7

为什么TFileStream.write产生不正确的数据?伤寒人7
EN

Stack Overflow用户
提问于 2018-07-07 20:25:06
回答 1查看 238关注 0票数 1

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

代码语言:javascript
复制
header := StringOfChar(char(0), 11*offsetSize);

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

代码语言:javascript
复制
C026A200160000000100000006000000264C656B63650000B2000000B04D45005C1EA200306CA20000000000

我希望输出文件应该包含

代码语言:javascript
复制
0000 0000 0000 0000 0000 0000

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

代码语言:javascript
复制
C026A200160000000100000006000000264C656B63650000B2000000B04D45005C1EA200306CA20000000000

(看起来是一样的)。

当我在Delphi 7中调试时,当标题中填充了0时,我就会看到它:

代码语言:javascript
复制
#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)填充它时,它包含.

代码语言:javascript
复制
#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

我的问题是,为什么会发生这种事?如果输出文件包含错误的数据,我做错了什么?

代码语言:javascript
复制
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.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-07 20:53:05

您的数据没有正确写入文件的原因是因为您没有正确地将header传递给Write()Write()以一个非类型化的var作为输入,并将header变量以原样传递给它,因此您要传递Write() -- header本身的内存地址。但是string包含一个指向存储在内存其他地方的字符数据的指针。因此,为了将这些数据写入文件,您需要取消对string指针的引用,从而将字符数据的内存地址传递给您。

另外,如果您不想检查Write()的返回值是否有错误,则应该使用WriteBuffer()

试试这个:

代码语言:javascript
复制
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;

或者:

代码语言:javascript
复制
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或字节数组,例如:

代码语言:javascript
复制
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;

或者:

代码语言:javascript
复制
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;

或者:

代码语言:javascript
复制
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;
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51226714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档