Frage

Ich habe eine Struktur wie unter dem gespeichert werden muss und von der Festplatte geladen werden.

 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;

Bis jetzt habe ich so etwas wie diese verwendet, um die Struktur zu speichern:

function
var F: FILE;
    Hdr: RSecStructure;
begin
...
 BlockWrite (F, Hdr, SizeOf(Hdr));   
...
end

Der obige Code arbeitete unter Delphi 7. Unter D2009 ich viele Warnmeldungen bekam, wenn ich Zuordnungen zwischen kurzen und Unicode-Strings zu machen. Bis jetzt habe ich es geschafft Delphi-Code zu schreiben, ohne jegliche Compiler-Warnungen oder Hinweise zu haben, und ich will so bleiben. Also brauche ich eine elegante war Strings zu speichern (Unicode wird groß sein, aber nicht kritisch) auf die Festplatte ohne Warnungen zu bekommen.

War es hilfreich?

Lösung

Alternativ können Sie speicherbare Kurz Unicode-String Datensatz deklarieren und implementieren implizite ‚string‘ und ‚von String‘ Konvertierungen.

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.

[Der obige Code zu Public Domain freigegeben und trägt keine Lizenzverpflichtungen.]

Andere Tipps

Diese String-Felder sind die gleichen in Delphi 2009, wie sie in allen früheren Versionen waren. ShortString ist kein Unicode-Typ.

So sollten Sie in der Lage sein, mit diesem Datensatz fortsetzen, wie sie ist.

Sie sagen, es funktioniert in Delphi 7. Ist es nicht Arbeit in Delphi 2009? Beschreiben Sie das Problem Sie haben.

Wollen Sie damit sagen, dass Sie eine feste Länge Unicode entspricht ShortString? Es gibt nicht ein, so dass Sie nicht einen Datensatz so haben können, haben sie fadenähnliche Unicode-Werte halten, und es direkt auf der Festplatte speichern.

Ich glaube nicht, das ist ein großes Problem, obwohl, da Ihr Plattenformat nicht mit dem aktuellen Format ohnehin kompatibel sein würde. Ihre Charaktere wären zu groß

Sie können eine Reihe von Zeichen verwenden:

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;

Das wird nicht ganz so echte String-Typen so bequem sein, aber es wird für die meisten Zwecke arbeiten.

Sie können auch einen normalen UnicodeString-Typ:

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;

Sie können nicht direkt auf die Festplatte speichern mehr, aber Sie sind auch nicht mehr auf 255 Zeichen beschränkt. Sie werden jede Zeichenfolge Feld separat speichern müssen. Stellen Sie sicher, dass die Zeichenfolge die Länge zu speichern, zu, oder Sie werden nicht wissen, wo eine Zeichenkette endet und die nächste beginnt, wenn es Zeit später Ihre Datei zu laden.

können Sie behalten bestehende Struktur (string [255]), Dateiformat bestehenden und auch korrekt Nicht-Unicode-Daten zuvor gespeicherten lesen, indem Sie wie folgt vor:

vor dem Schreiben Daten:

...
record.Name:= UTF8EncodeToShortString(Name);

, nachdem die Daten zu lesen:

...
Name:= UTF8ToString(record.Name);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top