web-dev-qa-db-ja.com

ファイルへの/からのMemoryStreamの保存と読み込み

構造体をMemoryStreamにシリアライズしています。シリアライズされた構造体を保存してロードしたいです。

では、MemoryStreamをファイルに保存し、それをファイルからロードする方法は?

233
Mahdi Ghiasi

MemoryStream.WriteToまたはStream.CopyTo(フレームワークバージョン4.5.2、4.5.1、4.5、4でサポート)メソッドを使用して、メモリストリームの内容を別のストリームに書き込むことができます。

memoryStream.WriteTo(fileStream);

更新:

fileStream.CopyTo(memoryStream);
memoryStream.CopyTo(fileStream);
318
adatapost

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

これはファイルを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);
}

.NET Framework 4以降では、FileStreamをMemoryStreamにコピーして、これと同じくらい簡単に元に戻すことができます。

MemoryStream ms = new MemoryStream();
using (FileStream file = new FileStream("file.bin", FileMode.Open, FileAccess.Read))
    file.CopyTo(ms);

そしてその逆(MemoryStreamからFileStreamへ):

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

たとえ例外があったとしても(ファイルI/Oで)ストリームは本当に破棄されるべきです - 節を使うことはこれのための私のお気に入りのアプローチです。

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

そしてそれを読み返すために:

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

ファイルが大きい場合は、読み取り操作でファイルサイズの合計の2倍のメモリが使用されることに注意してください 。その解決策の1つは、バイト配列からMemoryStreamを作成することです。次のコードでは、そのストリームに書き込みを行わないと仮定しています。

MemoryStream ms = new MemoryStream(bytes, writable: false);

私の調査(以下)は、内部バッファがあなたがそれを渡すのと同じバイト配列であることを示します、それでそれはメモリを節約するべきです。

byte[] testData = new byte[] { 104, 105, 121, 97 };
var ms = new MemoryStream(testData, 0, 4, false, true);
Assert.AreSame(testData, ms.GetBuffer());
58
Rob Church

短いバージョンを探している人のために:

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

File.WriteAllBytes("1.dat", memoryStream.ToArray()); 
31
Slai

ファイルに書き込むための総合的な答えは次のようになります。

MemoryStream ms = new MemoryStream();    
FileStream file = new FileStream("file.bin", FileMode.Create, FileAccess.Write);
ms.WriteTo(file);
file.Close();
ms.Close();
18
Berkay Turancı

ファイルをロードするために、私はこれがずっと好きです

MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(file))
{
    fs.CopyTo(ms);
}
14
ProVega

ファイルに保存

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

ファイルからロード

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

どこで

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;
        }
    }
}

もともとこのクラスの実装は投稿されています ここ

そして

[Serializable]
public class Car
{
    public string Name;
}
13

私はパネルコントロールを使用して画像を追加したりビデオをストリーミングしたりしますが、SQL Serverに Image またはMySQLを largeblob として保存できます。このコードは私にはとてもうまくいきます。見てみな。

ここで画像を保存します

MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); // here you can change the Image format
byte[] Pic_arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(Pic_arr, 0, Pic_arr.Length);
ms.Close();

そしてここであなたはロードすることができます、しかし私はPictureBoxコントロールを使いました。

MemoryStream ms = new MemoryStream(picarr);
ms.Seek(0, SeekOrigin.Begin);
fotos.pictureBox1.Image = System.Drawing.Image.FromStream(ms);

希望が役立ちます。

3
Leinad