[英]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.