如何通过C#将IStream存储到文件?

如何通过C#将IStream存储到文件?,c#,istream,C#,Istream,我正在使用一个返回IStream对象的第三方组件(System.Runtime.InteropServices.ComTypes.IStream)。我需要在那个IStream中获取数据并将其写入一个文件。我已经设法做到了,但是我对代码不是很满意 “strm”是我的IStream,下面是我的测试代码 // access the structure containing statistical info about the stream System.Runtime.InteropServices.

我正在使用一个返回IStream对象的第三方组件(System.Runtime.InteropServices.ComTypes.IStream)。我需要在那个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转换,但我想知道是否有比上面更好的方法来获得原始流长度?我对C#有点陌生,所以谢谢你的指点。

你不需要做那个转换,因为你可以从
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());
    }
}

这种方式(如果可行的话)内存效率更高,因为它只使用一个小内存块在这些流之间传输数据。

从MSDN:

实际读取的字节数可以是 小于字节数 如果发生错误或 过程中到达流的末端 读取操作。人数 返回的字节应始终为 与字节数相比 请求。如果是字节数 返回的值小于 请求的字节数,通常表示 Read方法试图读取超过 河的尽头


本文档说明,只要pcbRead小于cb,就可以循环和读取。

Rubens-感谢上面的示例代码。这对我来说确实澄清了一些事情。不幸的是,自从我发布它以来,我还没有测试过它,而且不会再测试了。那时,我会接受这个答案,或者在需要时发布更多的说明。myPtr应该初始化为0以上的值,因为如果init值为-1,它将永远不会进入while循环。您需要为该指针实际分配一些内存,而不仅仅是向其中抛出一个值,否则,
myPtr
将不会包含任何有用的内容。你必须读出数值
myPtr.ToInt32()
没有按照您的想法执行。此外,读取的字节数是一个
long
,因此需要读取
Int64
值并强制转换它。