2012-01-11 6 views
1

をしてください保存し、ロード、私はこの二分木構造を持っているとしますデルファイは、バイナリツリー

Type 
    TPMyTree = ^TMyTree; 
    TMyTree = Record 
     ID:Integer; 
     FullName:String[50];//<-------- fixed 
     addrs:String[50] // <----------- fixed 
     LeftT:TPMyTree; 
     RightT:TPMyTree; 
    end; 

私は保存してストリームからそれを読み込むことができますどのように?

+1

http://stackoverflow.com/questions/3820996/delphi-2010-how-to-save-a-whole-record-to-a-ファイル –

+0

私は質問自体に答えを出しましたが、質問する必要があります。なぜこれを行う必要がありますか?これ以上の演習でこれが必要な場合は、可変長文字列を固定したもの( 'string [number]'のように)を置き換えてツリーを構造化することをお勧めします。左と右のサブノードは実際のポインタではなく、バッファ。そうすれば、一度に1つのノードではなく、全体のインデックスを読み書きすることができます。これが大量のノードになる場合は、Bツリーのようにディスクで動作するように設計されたツリーデータ構造を調べてください。 –

+0

XML形式またはテキスト形式またはバイナリ形式で保存しますか? String [50]を使用して、バイナリ形式を使用したいと考えています。バイナリ形式はまったく使用せず、代わりにテキスト形式で保存することをお勧めします。あなたが与えた答えは、「可変長データはバイナリ形式で扱いにくい」と答えたので、あなたの質問を更新しました。私は言っただろう、二度と書いてはいけない。悪いアイデア。 –

答えて

1

ストリームで作業する場合、最も複雑な問題は可変長データを扱うことです。あなたの場合は、FullNameaddrsです。これらのフィールドのタイプはStringであるためです。最も簡単な解決策は、DelphiのストリームリーダーとライターのヘルパークラスTReaderTWriterを使用することです。これは文字列を扱う簡単な手段を提供するためです。他の点では、最も明白な解決策は、一度に1つのノードを再帰的にストリームに書き込むことです。

ブラウザウィンドウで書かれた警告、コード:

// This will save one node to the stream, using the TWriter helper. Takes 
// care of potential NIL's. 
procedure SaveBinaryTreeToStreamWriter(RootNode: TPMyTree; W: TWriter); 
begin 
    if Assigned(RootNode) then 
    begin 
     W.WriteBoolean(True); 
     W.WriteInteger(RootNode^.ID); 
     W.WriteString(RootNode^.FullName); 
     W.WriteString(RootNode^.addres); 
     SaveBinaryTreeToStreamWriter(RootNode^.LeftT, W); 
     SaveBinaryTreeToStreamWriter(RootNode^.RightT, W); 
    end 
    else 
    W.WriteBoolean(False); 
end; 

// This will read one NODE from the stream, using the TReader helper. 
// Uses the boolean "nil" marker saved by the writing routine to also 
// return "nil" if needed. 
function ReadBinaryTreeNodeFromReader(R: TReader):TPMyTree; 
begin 
    if R.ReadBoolean then 
    begin 
     Result := AllocMem(SizeOf(TMyTree)); 
     Result^.ID := R.ReadInteger; 
     Result^.FullName := R.ReadString; 
     Result^.addres := R.ReadString; 
     Result^.LeftT := ReadBinaryTreeNodeFromReader(R); 
     Result^.RightT := ReadBinaryTreeNodeFromReader(R); 
    end 
    else 
    Result := nil; 
end; 

// This simply creates the TWriter and then starts the recursive process of 
// writing the tree to stream. 
procedure SaveBinaryTreeToStream(RootNode: TPMyTree; Stream: TStream); 
var W:TWriter; 
begin 
    W := TWriter.Create(Stream, 128); 
    try 
    SaveBinaryTreeToStreamWriter(RootNode, W); 
    finally W.Free; 
    end; 
end;  

// This simply creates the TReader and then starts the recursive process of 
// reading the tree one node at a time: 
function ReadFromStream(Stream:TStream):TPMyTree; 
var R: TReader; 
begin 
    R := TReader.Create(Stream, 128); 
    try 
    Result := ReadBinaryTreeNodeFromReader(R); 
    finally R.Free; 
    end;  
end; 
+0

今すぐ FullNameとaddrsには固定サイズの – Alexis

+0

があります。 String [50]はAnsi Charactersを最大50個格納していることを意味し、そのレコードに格納するUnicode文字(Unicode Delphi版)はString [50]に格納することはできません。フィールド。 (文字型AnsiCharの固定長フィールド)。 –