在Delphi 2009下将字符串保存到磁盘

WeG*_*ars 1 delphi save delphi-2009

我有一个像下面这样的结构需要保存并从磁盘加载.

 RSecStructure= packed record
   Name               : string[255];       {NEED UNICODE SUPPORT HERE}
   ScreenName         : string[255];
   OrigFileName       : string[255];                    
   Prim               : string[255];                                           
   ParentVersion      : integer;
   sTag1              : string[255];      
   sTag2              : string[255];
   sTag3              : string[255];
   sTag4              : string[255];
   DateAdd            : TDateTime;
   DateModify         : TDateTime;
  end;
Run Code Online (Sandbox Code Playgroud)

到目前为止,我使用了类似的东西来保存结构:

function
var F: FILE;
    Hdr: RSecStructure;
begin
...
 BlockWrite (F, Hdr, SizeOf(Hdr));   
...
end
Run Code Online (Sandbox Code Playgroud)

上面的代码在Delphi 7下工作.在D2009下,当我在短字符串和Unicode字符串之间进行分配时,我收到了很多警告消息.到目前为止,我设法编写Delphi代码而没有任何编译器警告或提示,我想保持这样.所以我需要一个优雅的方法是将磁盘保存(Unicode将很好但不是关键)到磁盘而不会收到警告.

Rob*_*edy 8

这些字符串字段在Delphi 2009中与在以前的所有版本中相同.ShortString不是Unicode类型.

所以你应该能够继续按原样继续使用该记录.

你说这在Delphi 7工作是否德尔福2009年工作吗?描述你遇到的问题.

你的意思是说你想要一个固定长度的Unicode等价ShortString吗?没有一个,所以你不能有这样的记录,让它保持类似字符串的Unicode值,并将其直接保存到磁盘.

但是,我不认为这是一个主要问题,因为你的磁盘格式无论如何都与你当前的格式不兼容:你的角色太大了.

您可以使用一组字符:

type
  TSecStructure = packed record
    Name               : array[0..255] of UnicodeChar;
    ScreenName         : array[0..255] of UnicodeChar;
    OrigFileName       : array[0..255] of UnicodeChar;
    Prim               : array[0..255] of UnicodeChar;
    ParentVersion      : integer;
    sTag1              : array[0..255] of UnicodeChar;
    sTag2              : array[0..255] of UnicodeChar;
    sTag3              : array[0..255] of UnicodeChar;
    sTag4              : array[0..255] of UnicodeChar;
    DateAdd            : TDateTime;
    DateModify         : TDateTime;
  end;
Run Code Online (Sandbox Code Playgroud)

这不会像真正的字符串类型那样方便,但它可以用于大多数目的.

您也可以使用普通UnicodeString类型:

type
  TSecStructure = record
    Name               : UnicodeString;
    ScreenName         : UnicodeString;
    OrigFileName       : UnicodeString;
    Prim               : UnicodeString;
    ParentVersion      : integer;
    sTag1              : UnicodeString;
    sTag2              : UnicodeString;
    sTag3              : UnicodeString;
    sTag4              : UnicodeString;
    DateAdd            : TDateTime;
    DateModify         : TDateTime;
  end;
Run Code Online (Sandbox Code Playgroud)

您不能再将其直接保存到磁盘,但您也不再限制为255个字符.您必须分别存储每个字符串字段.确保也存储字符串的长度,或者你不知道一个字符串的结束位置,以及下一个字符串何时开始加载文件.


gab*_*abr 6

或者,您可以声明可存储的短unicode字符串记录,并实现隐式'to string'和'from string'转换.

program TestShortUnicodeString;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TShortUnicodeString = record
  private
    Data: array [0..255] of char; //WARNING - NOT initialized to an empty string
  public
    class operator Implicit(const sus: TShortUnicodeString): string; inline;
    class operator Implicit(const ws: string): TShortUnicodeString; inline;
  end;

class operator TShortUnicodeString.Implicit(const sus: TShortUnicodeString): string;
begin
  Result := StrPas(sus.Data);
end;

class operator TShortUnicodeString.Implicit(const ws: string): TShortUnicodeString;
begin
  // too long strings are silently truncated
  StrPLCopy(Result.Data, ws, Length(Result.Data)-1);
end;

type
  TTestRec = record
    ws1: TShortUnicodeString;
    ws2: TShortUnicodeString;
  end;

var
  f    : file;
  test1: TTestRec;
  test2: TTestRec;

begin
  test1.ws1 := '6*9 =';
  test1.ws2 := ' 42';
  AssignFile(f, 'test.dat');
  Rewrite(f, 1);
  BlockWrite(f, test1, SizeOf(test1));
  CloseFile(f);
  AssignFile(f, 'test.dat');
  Reset(f, 1);
  Assert(FileSize(f) = SizeOf(test2));
  BlockRead(f, test2, SizeOf(test2));
  CloseFile(f);
  Writeln(string(test2.ws1), string(test2.ws2));
  Readln;
end.
Run Code Online (Sandbox Code Playgroud)

[上述代码已发布到公共领域,不承担任何许可义务.]