簡體   English   中英

為什么TFileStream.write產生不正確的數據? 德菲7

[英]Why TFileStream.write produces incorrect data? Dephi 7

我試圖創建一個函數/方法,該函數/方法應寫入標頭為零的文件

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.

您的數據未正確寫入文件的原因是因為您沒有正確將header傳遞給Write() Write()接受一個無類型的var作為輸入,然后按原樣將其傳遞給header變量,因此您將Write()傳遞給header本身的內存地址。 但是string包含指向存儲在內存中其他位置的字符數據的指針。 因此,為了將該數據寫入文件,您需要取消引用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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM