2009-07-31 8 views
1

ショートフォーム:ポインタからストリームを作成することは可能ですか?ポインタをデルファイでインクリメント/ポインタからストリームを作成

私は、読みたいファイルデータを指すポインタを持っています。 WriteBuffer()を使用してポインタからTFileStreamにデータを転送しました。これは動作します。しかし、今度はプログレスバーを表示するためにそれを賢明に読んでみたい。ですから、私はそれを段階的に読む必要があります。

私は選択肢にあります

1)ポインタのバフをインクリメントし、いつものように)WriteBufferメソッドを(使用しています。 (WriteBufferは常に先頭から読み込みますので、ポインタをインクリメントする必要があります)

2)ポインタからストリームを作成します。これは可能ですか?

コード:

var InputStream : TMemoryStream; 
    Buff: Pointer; 


    Header: TOCHeader; 
begin 

// Here I get the pointer 
Size := GetOverlay(Buff); 

// Transfer data to memory stream 
InputStream.WriteBuffer(Buff^, SizeOf(Header)); 

InputStream.Seek(0, soFromBeginning); 

// Read the header 
InputStream.ReadBuffer(Header, SizeOf(Header)); 

// Increment the pointer. Doesn't work :-(. Message Ordinal type required 
Inc(Buff, SizeOf(TOC)); 
+0

あなたはあなたのコード内の2つのInputStream変数を持っています。あなたはそれを読んでそれに書きます。明確にできますか? – mghie

+0

ああ、すみません。私はそれを修正しました。私は重要な変数とコードフレーズをコピーしたところで、InputStreamの定義は非常に重要であるようです。 – Simon

+0

ストリームへの書き込みと読み出しの間で、ストリームの位置をリセットする必要があることに注意してください。現在のコードでは例外が発生します。 – mghie

答えて

1

あなたの質問を読んだときに、私の心に疑問が浮かび上がる。あなたはfiledataへのポインタを持っています(ディスクから私は推測しますか?)あなたはそのポインタからのデータでフィルストリームを埋めています(あなたの質問では、代わりにmemorystreamを埋めます)。あなたが読んでいるファイルを開くのにTFileStreamを使わないのはなぜですか?

var 
    FileStream: TFileStream; 
    Header: TOCHeader; 
begin 
    FileStream := TFileStream.Create('c:\fileIWantToRead.txt', fmOpenRead); 
    FileStream.ReadBuffer(Header, SizeOf(Header)); 
    <...> 
end; 

あなたのポインタをインクリメントしたい場合は、最初の型のポインタにキャストするので、コンパイラは、ポインタを向上させる方法を知っています。ここで行うだろう

Inc(PByte(Buff), SizeOf(TOC)); //sizeof returns size in bytes, so cast pointer to a bytepointer 
+0

ありがとう、ありがとうございました。私は自己解凍ファイルを作成するために現在実行中のEXEからデータを読み込みたいので、私はTFileStreamを使用できません。あなたの提案されたソリューションがコンパイルされ、私はそれが動作するようになると受け入れられた答えとしてマークします;-)。 – Simon

+1

mghieの投稿でもわかるように、TFileStreamは 'c:\ fileIWantToRead.txt'に限定されず、あなたもexeファイルを開くことができます。 –

2

あなたはGetOverlay()から受け取ったアドレスとサイズを使用して、コンストラクタでSetPointer()を呼び出して、独自のTCustomMemoryStream子孫を作成することができます。詳細については、TCustomMemoryStreamのDelphiドキュメントを参照してください。

編集:

まあ、これはあなたの質問とは何の関係もありませんが、コメントに、あなたが唯一のストリームを介し実行されている実行可能ファイルから読み込むしたいことを書きます。これを行うには十分に簡単です:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Str: TStream; 
begin 
    Str := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone); 
    try 
    Caption := Format('Size of executable: %u bytes', [Str.Size]); 
    // start to read the contents of the file ... 

    finally 
    Str.Free; 
    end; 
end; 

私は誰かが実際にメモリのチャンクへのポインタから(読み取り専用)ストリームを作成したい場合には、オリジナルの答えを残します。

+0

私は自分のプログラムの実装を開始したときにそれを試みましたが、ファイルが現在使用中であるというエラーがあり、それはできないと思っていました...試しましたか? – Simon

+1

はい私は本当にあります。ファイルへのアクセスに問題がある場合は、SysInternalsツールを使用してください。このツールは、他のプログラムがファイルを開いた(排他的に)ものを表示します。 – mghie

+0

私はあなたが私の問題を誤解していないことを願っています:私は現在実行中のexeを読まなければなりません、アプリケーションはそれ自身から資源を引き出すためにそれ自身を読む必要があります。 (SFXアーカイブのように...) – Simon

関連する問題