2

我正在使用返回 IStream 对象 (System.Runtime.InteropServices.ComTypes.IStream) 的第 3 方组件。我需要获取该 IStream 中的数据并将其写入文件。我已经设法完成了,但我对代码并不满意。

“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 to int cast,但我想知道是否没有比上面更好的方法来获得原始流长度?我对 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 回答