How to save IStream to file via C #?
I am working with a third party component that returns an IStream object (System.Runtime.InteropServices.ComTypes.IStream). I need to take data in this IStream and write it to a file. I managed it, but I'm not very 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 least I don't like long input like above, but I'm wondering if there isn't a better way to get the original stream length than above? I'm a bit new to C #, so thanks for any pointers.
source to share
You don't need to do this as you can read data from the 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 method (if it works) is more memory efficient because it just uses a small block of memory to transfer data between these threads.
source to share
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 may be less than the number of bytes if an error occurs or if the end of the stream is reached during a read operation. The number of bytes should always be compared to the number of bytes requested. If the number of bytes returned is less than the number of bytes, this usually means the reader tried to read the end of the stream.
This documentation says you can loop and read if pcbRead is smaller than cb.
source to share