开发者

How to store an IStream to a file via C#?

I'm working with a 3rd party component that returns an IStream object (System.Runtime.InteropServices.ComTypes.IStream). I need to take the data in that IStrea开发者_运维百科m and write it to a file. I've managed to get that done, but I'm not really happy with the code.

With "strm" being my IStream, here's my test code...

// 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);

At the very least, I don't like the long to int cast as commented above, but I wonder if there's not a better way to get the original stream length than the above? I'm somewhat new to C#, so thanks for any pointers.


You don't need to do that cast, as you can read data from IStream source in chunks.

// ...
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());
    }
}

This way (if works) is more memory efficient, as it just uses a small memory block to transfer data between that streams.


System.Runtime.InteropServices.ComTypes.IStream is a wrapper for ISequentialStream.

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

The actual number of bytes read can be less than the number of bytes requested if an error occurs or if the end of the stream is reached during the read operation. The number of bytes returned should always be compared to the number of bytes requested. If the number of bytes returned is less than the number of bytes requested, it usually means the Read method attempted to read past the end of the stream.

This documentation says, that you can loop and read as long as pcbRead is less then cb.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜