2009-03-07 35 views
1

私は以下のようなディスクから保存してロードする必要がある構造を持っています。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; 

私は構造を保存するには、このようなものを使用していた今まで:上記のコードは、D2009の下のDelphi 7の下で働い

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

私は短い間の割り当てを行うとき、私は警告メッセージの多くを得ましたおよびUnicode文字列です。 これまでは、コンパイラの警告やヒントがなくてもDelphiコードを書くことができました。そのようにしたいと思います。 警告を出さずに文字列を保存するためには、エレガントなものが必要です(Unicodeは重要ですが重要ではありません)。

答えて

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. 

[上のコードは、パブリックドメインにリリースされ、ライセンス義務はありません。]

+0

'TShortUnicodeString = record'のようなものを' string [N] 'と同様に書くことができます(テストするためのD2010はありません)。 –

8

これらの文字列フィールドは、Delphi 2009では以前のすべてのバージョンと同じです。 ShortStringはUnicode型ではありません。

したがって、そのレコードをそのまま使用することができます。

あなたはそれがデルファイ7で働いていると言います。それはではなく、はDelphi 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; 

実際の文字列型ほど便利なことはないだろうが、それはほとんどの目的のために動作します。

あなたはまた、通常の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; 

あなたはもうディスクに直接それを保存することはできませんが、あなたも、もはや255文字に制限されていないです。各文字列フィールドは別々に格納する必要があります。文字列の長さも保存してください。後でファイルを読み込むときに、文字列の終わりと終わりが分かりません。

+0

>配列[0..255] of UnicodeChar; これはそれを行うと思います。どうもありがとう。 – Ampere

+0

これは、ASCII文字のストレージサイズを2倍にします。代わりに、ShortStringを使用してUTF8文字列をその中に格納することができます(UTF8Encode、UTF8ToString) –

+0

>これは、ASCII文字のストレージサイズを2倍にします。 これは問題ありません。ありがとう。 – Ampere

2

あなたは、既存の構造(文字列[255])、既存のファイル形式を維持しても、正しく以前に、以下を使用して保存された非Unicodeデータ読み取ることができます。データを書き込む前に

を:

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

データを読み取った後:

... 
Name:= UTF8ToString(record.Name); 
関連する問題