Save and load MemoryStream to/from a file
Solution 1
You may use MemoryStream.WriteTo
or Stream.CopyTo
(supported in framework version 4.5.2, 4.5.1, 4.5, 4) methods to write content of memory stream to another stream.
memoryStream.WriteTo(fileStream);
Update:
fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
Solution 2
Assuming that MemoryStream name is ms
.
This code writes down MemoryStream to a file:
using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write)) {
byte[] bytes = new byte[ms.Length];
ms.Read(bytes, 0, (int)ms.Length);
file.Write(bytes, 0, bytes.Length);
ms.Close();
}
and this reads a file to a MemoryStream :
using (MemoryStream ms = new MemoryStream())
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read)) {
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
}
In .Net Framework 4+, You can simply copy FileStream to MemoryStream and reverse as simple as this:
MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read))
file.CopyTo(ms);
And the Reverse (MemoryStream to FileStream):
using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
ms.CopyTo(file);
Solution 3
The stream should really by disposed of even if there's an exception (quite likely on file I/O) - using clauses are my favourite approach for this, so for writing your MemoryStream, you can use:
using (FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write)) {
memoryStream.WriteTo(file);
}
And for reading it back:
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read)) {
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
}
If the files are large, then it's worth noting that the reading operation will use twice as much memory as the total file size. One solution to that is to create the MemoryStream from the byte array - the following code assumes you won't then write to that stream.
MemoryStream ms = new MemoryStream(bytes, writable: false);
My research (below) shows that the internal buffer is the same byte array as you pass it, so it should save memory.
byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());
Solution 4
For anyone looking for the short versions:
var memoryStream = new MemoryStream(File.ReadAllBytes("1.dat"));
File.WriteAllBytes("1.dat", memoryStream.ToArray());
Solution 5
The combined answer for writing to a file can be;
MemoryStream ms = new MemoryStream();
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
Mahdi Ghiasi
Updated on July 08, 2022Comments
-
Mahdi Ghiasi almost 2 years
I am serializing an structure into a
MemoryStream
and I want to save and load the serialized structure.So, How to Save a
MemoryStream
into a file and also load it back from file? -
Philter about 11 yearsCan I ask why you use FileMode.Create in the read sample vs FileMode.Open?
-
Gman about 11 yearsIn the first code block, instead of manually copying memory stream to array, you can use built-in
ms.ToArray()
function. -
Gregory Khrapunovich over 10 yearsIt's important to set ms.Position = 0, otherwise byte array (and file) will contain all zeros.
-
FrenkyB over 10 yearsIf file is opened in Microsoft Word - is there a way for creating a memory stream from that file? I am receiving an error 'file is opened by another process'
-
Mark Adamson almost 10 yearsmemoryStream.CopyTo didn't seem to work for me, while WriteTo did. I think perhaps it was because my memoryStream.Position wasn't 0
-
AnorZaken over 8 yearsYes that is correct. The difference between them is that CopyTo copies from whatever the current position is instead of always from the begining like WriteTo does.
-
Kristopher over 8 years@FrenkyB I also run into this a lot. If you have the file open in Word or some other app then you can't get do it. Just close the file in Word.
-
Fabricio Araujo about 7 years@Fernando68 the construct
using (...){ }
has the exactly the same effect. -
Martin Backasch over 6 yearsAdding
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
beforeCopyTo
will set the current position to 0, so thatCopyTo
will copy the complete stream. -
Rebecca over 5 yearsJust as a warning to others 'using (FileStream' and 'ms.CopyTo(file)' sets the position tothe end of the file and you need to reset the memorystream afterwards.
-
ridecar2 almost 5 years@FrenkyB Can you do a File.Copy? I have found that to work, then read from that file into a stream and delete the new file... horrible, but seems to work.
-
Paras Parmar over 3 years@GregoryKhrapunovich , Its like a cassete tape, while we create it... we write to the very end. Now the tape has to be rewound before we put it in the walkman.
-
Darpan Gupta almost 3 yearsThanks.You made it so simple and in 2 lines only.
-
CorrM about 2 yearsKeep in mind this will re-allocate the whole buffer (MemoryStream.ToArray)
byte[] copy = GC.AllocateUninitializedArray<byte>(count);