Speichern von Strings auf der Festplatte unter Delphi 2009
-
05-07-2019 - |
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.
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);