将MemoryStream保存并加载到文件中

Mah*_*asi 264 c# io memorystream file stream

我正在将结构序列化为a MemoryStream,我想保存并加载序列化结构.

那么,如何将MemoryStream文件保存到文件中并将其从文件中加载回来?

ada*_*ost 344

您可以使用MemoryStream.WriteToStream.CopyTo(在框架版本4.5.2,4.5.1,4.5,4中支持)方法将内存流的内容写入另一个流.

memoryStream.WriteTo(fileStream);
Run Code Online (Sandbox Code Playgroud)

更新:

fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
Run Code Online (Sandbox Code Playgroud)

  • WriteStream.CopyTo似乎对我不起作用,而WriteTo则没有.我想也许是因为我的memoryStream.Position不是0 (10认同)
  • 对,那是正确的.它们之间的区别在于CopyTo从当前位置复制而不是像WriteTo那样始终从最开始复制. (8认同)
  • 添加[`[file | memory] ​​Stream.Seek(0,SeekOrigin.Begin);`](https://msdn.microsoft.com/zh-cn/library/system.io.stream.seek(v = vs。 110).aspx),然后将“复制到”将当前位置设置为0,以便“复制到”将复制完整的流。 (2认同)

Ash*_*ani 252

假设MemoryStream名称是ms.

此代码将MemoryStream写入文件:

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();
}
Run Code Online (Sandbox Code Playgroud)

这会将文件读入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);
}
Run Code Online (Sandbox Code Playgroud)

在.Net Framework 4+中,您可以简单地将FileStream复制到MemoryStream,并且反向就像这样简单:

MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read))
    file.CopyTo(ms);
Run Code Online (Sandbox Code Playgroud)

和Reverse(MemoryStream到FileStream):

using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
    ms.CopyTo(file);
Run Code Online (Sandbox Code Playgroud)

  • 设置ms.Position = 0非常重要,否则字节数组(和文件)将包含全零. (5认同)
  • 在第一个代码块中,您可以使用内置的`ms.ToArray()`函数,而不是手动将内存流复制到数组. (4认同)
  • 这适用于旧版本的.NET (3认同)
  • 就像警告其他人“使用(FileStream”和“ms.CopyTo(file)”将位置设置为文件末尾一样,之后您需要重置内存流。 (3认同)

Rob*_*rch 62

即使存在异常(很可能是文件I/O),流也应该被处理掉 - 使用子句是我最喜欢的方法,所以对于编写MemoryStream,你可以使用:

using (FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write)) {
    memoryStream.WriteTo(file);
}
Run Code Online (Sandbox Code Playgroud)

阅读它:

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);
}
Run Code Online (Sandbox Code Playgroud)

如果文件很大,那么值得注意的是,读取操作将使用两倍于总文件大小的内存.一种解决方案是从字节数组创建MemoryStream - 以下代码假定您不会写入该流.

MemoryStream ms = new MemoryStream(bytes, writable: false);
Run Code Online (Sandbox Code Playgroud)

我的研究(如下)显示内部缓冲区与传递它的字节数组相同,因此它应该节省内存.

byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());
Run Code Online (Sandbox Code Playgroud)


Sla*_*lai 37

对于任何寻找短版本的人:

var memoryStream = new MemoryStream(File.ReadAllBytes("1.dat"));

File.WriteAllBytes("1.dat", memoryStream.ToArray()); 
Run Code Online (Sandbox Code Playgroud)

  • 请记住,这将重新分配整个缓冲区 (MemoryStream.ToArray) `byte[] copy = GC.AllocateUninitializedArray<byte>(count);` (2认同)

Ber*_*ncı 18

写入文件的组合答案可以是;

MemoryStream ms = new MemoryStream();    
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
Run Code Online (Sandbox Code Playgroud)


Pro*_*ega 14

对于加载文件,我更喜欢这个

MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
    fs.CopyTo(ms);
}
Run Code Online (Sandbox Code Playgroud)


Vad*_*hev 13

保存到文件中

Car car = new Car();
car.Name = "Some fancy car";
MemoryStream stream = Serializer.SerializeToStream(car);
System.IO.File.WriteAllBytes(fileName, stream.ToArray());
Run Code Online (Sandbox Code Playgroud)

从文件加载

using (var stream = new MemoryStream(System.IO.File.ReadAllBytes(fileName)))
{
    Car car = (Car)Serializer.DeserializeFromStream(stream);
}
Run Code Online (Sandbox Code Playgroud)

哪里

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace Serialization
{
    public class Serializer
    {
        public static MemoryStream SerializeToStream(object o)
        {
            MemoryStream stream = new MemoryStream();
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, o);
            return stream;
        }

        public static object DeserializeFromStream(MemoryStream stream)
        {
            IFormatter formatter = new BinaryFormatter();
            stream.Seek(0, SeekOrigin.Begin);
            object o = formatter.Deserialize(stream);
            return o;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最初这个类的实现已经发布在这里

[Serializable]
public class Car
{
    public string Name;
}
Run Code Online (Sandbox Code Playgroud)