Delphi Tokyo-我并创建一个配置文件。我正在使用BlockWrite写入配置文件,然后使用BlockRead读取它。我在读取字符串时出了点问题。我得到的似乎是亚洲字符...
我认为问题在于定义ReadString例程的方式。
这是我的WriteString例程
procedure WriteString(s: ShortString);
begin { WriteString }
BlockWrite(fil, s, succ(length(s)));
end; { WriteString }
我的ReadString例程应该给我相同的数据,但事实并非如此。 这是ReadString代码。
function ReadString: string;
var
count: Cardinal;
l: integer;
begin
BlockRead(fil, l, sizeof(integer), count);
SetLength(Result, l);
BlockRead(fil, Result[1], l, count);
end;
从配置文件读取的第一个值是布尔值,并且似乎已正确读取了文件。下一个值是一个字符串,并且被弄乱了。任何帮助表示赞赏。
这里是FULL WriteConfig和ReadConfig例程,以及一个SetConfigValues,它仅创建一些测试数据。
procedure SetConfigValues;
begin
//
gCMD_Globals.Load_Table := True;
gCMD_Globals.DB_Tablename := 'my Test Table';
gCMD_Globals.Create_Backup := True;
gCMD_Globals.Delete_Existing_Backup := False;
gCMD_Globals.Truncate_Existing_Table := True;
SetLength(gCMD_Detail, 2);
gCMD_Detail[0].CommandType := 'CMD1';
gCMD_Detail[0].P1 := 'P11';
gCMD_Detail[0].P2 := 'P21';
gCMD_Detail[0].P3 := 'P31';
gCMD_Detail[1].CommandType := 'CMD1';
gCMD_Detail[1].P1 := 'P12';
gCMD_Detail[1].P2 := 'P22';
gCMD_Detail[1].P3 := 'P32';
end;
procedure WriteConfigFile(FileName: string);
var
fil: file;
i: integer;
num: word; { allows up to 65535 records }
const
ver: byte = LatestFileVersion;
procedure WriteString(s: ShortString);
begin { WriteString }
BlockWrite(fil, s, succ(length(s)));
end; { WriteString }
begin { WriteConfigFile }
assignFile(fil, FileName);
rewrite(fil, 1); { Create the file }
BlockWrite(fil, ver, sizeof(ver)); { Write the file version }
// Now we need to write the gCMD_Globals record
with gCMD_Globals do
begin { write the data }
BlockWrite(fil, Load_Table, sizeof(Load_Table));
WriteString(DB_Tablename);
BlockWrite(fil, Create_Backup, sizeof(Create_Backup));
BlockWrite(fil, Delete_Existing_Backup, sizeof(Delete_Existing_Backup));
BlockWrite(fil, Truncate_Existing_Table, sizeof(Truncate_Existing_Table));
end;
num := length(gCMD_Detail);
BlockWrite(fil, num, sizeof(num)); { Write the number of records }
for i := 0 to high(gCMD_Detail) do
with gCMD_Detail[i] do
begin { write the data }
WriteString(CommandType);
WriteString(P1);
WriteString(P2);
WriteString(P3);
end; { with }
CloseFile(fil);
end; { WriteConfigFile }
procedure ReadConfigFile(FileName: string);
var
fil: file;
i: integer;
num: word; { allows up to 65535 records }
ver: byte;
function ReadString: string;
var
count: Cardinal;
l: integer;
begin
BlockRead(fil, l, sizeof(integer), count);
SetLength(Result, l);
BlockRead(fil, Result[1], l, count);
end;
begin { ReadFile }
assignFile(fil, FileName);
reset(fil, 1); { Open the file }
BlockRead(fil, ver, sizeof(ver)); { Read the file version }
// Now we need to write the gCMD_Globals record
with gCMD_Globals do
begin { write the data }
BlockRead(fil, Load_Table, sizeof(Load_Table));
DB_Tablename := ReadString;
BlockRead(fil, Create_Backup, sizeof(Create_Backup));
BlockRead(fil, Delete_Existing_Backup, sizeof(Delete_Existing_Backup));
BlockRead(fil, Truncate_Existing_Table, sizeof(Truncate_Existing_Table));
end;
BlockRead(fil, num, sizeof(num)); { Read the number of records }
SetLength(gCMD_Detail, num);
for i := 0 to high(gCMD_Detail) do
with gCMD_Detail[i] do
begin { Read the data }
CommandType := ReadString;
P1 := ReadString;
P2 := ReadString;
P3 := ReadString;
end; { with }
CloseFile(fil);
end; { ReadConfigFile }
答案 0 :(得分:2)
ShortString
是使用1字节长度的8位字符串类型。您正在正确地写入ShortString
到文件中(假定文件的“记录”大小已预先设置为1),但是您没有正确地读回它。您正在读取4字节的integer
而不是1字节的AnsiChar
/ Byte
作为字符串长度,然后您将8位字符读入16位{{ 1}},而不是UnicodeString
。
改为使用此:
ShortString
不过,我完全不建议使用function ReadString: string;
var
len: Byte;
s: ShortString;
begin
BlockRead(fil, len, 1);
SetLength(s, len);
BlockRead(fil, s[1], len);
Result := string(s);
end;
。您正在使用Unicode版本的Delphi,因此,如果您可以随意更改文件布局,建议您将ShortString
用作WriteString()
作为输入,并将其转换为UTF-8进行存储,然后再进行(Unicode)String
进行相反操作,例如:
ReadString()
答案 1 :(得分:1)
对于短字符串,长度为ord(s [0]),并且仅写入一个字节。但是,您将四个字节读入l。因此,您不能指望它能起作用。作为解决方法,可以将长度写为整数,也可以读字节变量l。