2

IStream オブジェクト (System.Runtime.InteropServices.ComTypes.IStream) を返すサードパーティ コンポーネントを使用しています。その ISt​​ream のデータを取得してファイルに書き込む必要があります。私はそれを成し遂げることができましたが、コードにはあまり満足していません.

「strm」が私のIStreamであるため、これが私のテストコードです...

// access the structure containing statistical info about the stream
System.Runtime.InteropServices.ComTypes.STATSTG stat;
strm.Stat(out stat, 0);
System.IntPtr myPtr = (IntPtr)0;

// get the "cbSize" member from the stat structure
// this is the size (in bytes) of our stream.
int strmSize = (int)stat.cbSize; // *** DANGEROUS *** (long to int cast)
byte[] strmInfo = new byte[strmSize];
strm.Read(strmInfo, strmSize, myPtr);

string outFile = @"c:\test.db3";
File.WriteAllBytes(outFile, strmInfo);

少なくとも、上記のように long から int へのキャストは好きではありませんが、上記よりも元のストリームの長さを取得するためのより良い方法はないのでしょうか? 私はC#に少し慣れていないので、ポインタに感謝します。

4

2 に答える 2

2

IStreamソースからデータをチャンクで読み取ることができるため、そのキャストを行う必要はありません。

// ...
System.IntPtr myPtr = (IntPtr)-1;
using (FileStream fs = new FileStream(@"c:\test.db3", FileMode.OpenOrCreate))
{
    byte[] buffer = new byte[8192];
    while (myPtr.ToInt32() > 0)
    {
        strm.Read(buffer, buffer.Length, myPtr);
        fs.Write(buffer, 0, myPtr.ToInt32());
    }
}

この方法 (機能する場合) は、小さなメモリ ブロックを使用してストリーム間でデータを転送するだけなので、メモリ効率が向上します。

于 2009-10-15T14:47:43.260 に答える
1

System.Runtime.InteropServices.ComTypes.IStream は ISequentialStream のラッパーです。

MSDN から: http://msdn.microsoft.com/en-us/library/aa380011(VS.85).aspx

エラーが発生した場合、または読み取り操作中にストリームの最後に到達した場合、読み取られる実際のバイト数は、要求されたバイト数よりも少なくなることがあります。返されるバイト数は、要求されたバイト数と常に比較する必要があります。返されたバイト数が要求されたバイト数よりも少ない場合は、通常、Read メソッドがストリームの末尾を超えて読み取ろうとしたことを意味します。

このドキュメントには、pcbRead が cb より小さい限り、ループして読み取ることができると書かれています。

于 2009-10-15T14:53:15.713 に答える