Jika Anda perlu menyimpan ke file, mengapa Anda menggunakan MemoryStream?
Oded
@Oded Apa yang harus saya gunakan? Bisakah Anda memberi saya contoh?
Mahdi Ghiasi
Jawaban:
365
Anda dapat menggunakan MemoryStream.WriteToatau Stream.CopyTo(didukung dalam kerangka versi 4.5.2, 4.5.1, 4.5, 4) metode untuk menulis konten aliran memori ke aliran lain.
memoryStream.CopyTo tampaknya tidak berfungsi untuk saya, sementara WriteTo melakukannya. Saya pikir mungkin itu karena memoryStream.Posisi saya bukan 0
Mark Adamson
10
Ya itu benar. Perbedaan di antara mereka adalah bahwa CopyTo menyalin dari posisi apa pun saat ini bukannya selalu dari awal seperti yang dilakukan WriteTo.
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write)){byte[] bytes =newbyte[ms.Length];
ms.Read(bytes,0,(int)ms.Length);
file.Write(bytes,0, bytes.Length);
ms.Close();}
dan ini membaca file ke MemoryStream:
using (MemoryStream ms =newMemoryStream())
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[file.Length];
file.Read(bytes,0,(int)file.Length);
ms.Write(bytes,0,(int)file.Length);}
Di .Net Framework 4+, Anda cukup menyalin FileStream ke MemoryStream dan membalikkannya sesederhana ini:
MemoryStream ms =newMemoryStream();
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read))
file.CopyTo(ms);
Dan Reverse (MemoryStream ke FileStream):
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write))
ms.CopyTo(file);
Bisakah saya bertanya mengapa Anda menggunakan FileMode.Create dalam sampel read vs FileMode.Open?
Philter
6
Di blok kode pertama, alih-alih secara manual menyalin aliran memori ke array, Anda dapat menggunakan ms.ToArray()fungsi bawaan.
Gman
5
Penting untuk mengatur ms.Position = 0, jika array byte (dan file) akan berisi semua nol.
Gregory Khrapunovich
1
@ Fernando68 konstruk using (...){ }memiliki efek yang persis sama.
Fabricio Araujo
2
Sama seperti peringatan kepada orang lain 'menggunakan (FileStream' dan 'ms.CopyTo (file)' menetapkan posisi untuk akhir file dan Anda perlu mengatur ulang aliran memori sesudahnya.
Rebecca
64
Aliran harus benar-benar dibuang meskipun ada pengecualian (sangat mungkin pada file I / O) - menggunakan klausa adalah pendekatan favorit saya untuk ini, jadi untuk menulis MemoryStream Anda, Anda dapat menggunakan:
using (FileStream file =newFileStream("file.bin",FileMode.Create,FileAccess.Write)){
memoryStream.WriteTo(file);}
Dan untuk membacanya kembali:
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read)){byte[] bytes =newbyte[file.Length];
file.Read(bytes,0,(int)file.Length);
ms.Write(bytes,0,(int)file.Length);}
Jika file berukuran besar, maka perlu dicatat bahwa operasi membaca akan menggunakan memori dua kali lebih banyak dari total ukuran file . Salah satu solusi untuk itu adalah membuat MemoryStream dari array byte - kode berikut mengasumsikan Anda tidak akan menulis ke aliran itu.
MemoryStream ms =newMemoryStream(bytes, writable:false);
Penelitian saya (di bawah) menunjukkan bahwa buffer internal adalah array byte yang sama dengan yang Anda lewati, sehingga seharusnya menghemat memori.
byte[] testData =newbyte[]{104,105,121,97};var ms =newMemoryStream(testData,0,4,false,true);Assert.AreSame(testData, ms.GetBuffer());
Car car =newCar();
car.Name="Some fancy car";MemoryStream stream =Serializer.SerializeToStream(car);System.IO.File.WriteAllBytes(fileName, stream.ToArray());
Muat dari file
using (var stream =newMemoryStream(System.IO.File.ReadAllBytes(fileName))){Car car =(Car)Serializer.DeserializeFromStream(stream);}
dimana
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Serialization{publicclassSerializer{publicstaticMemoryStreamSerializeToStream(object o){MemoryStream stream =newMemoryStream();IFormatter formatter =newBinaryFormatter();
formatter.Serialize(stream, o);return stream;}publicstaticobjectDeserializeFromStream(MemoryStream stream){IFormatter formatter =newBinaryFormatter();
stream.Seek(0,SeekOrigin.Begin);object o = formatter.Deserialize(stream);return o;}}}
Awalnya implementasi kelas ini telah diposting di sini
Jika file dibuka di Microsoft Word - adakah cara untuk membuat aliran memori dari file itu? Saya menerima pesan kesalahan 'file dibuka oleh proses lain'
FrenkyB
@FrenkyB Saya juga sering mengalami hal ini. Jika file terbuka di Word atau aplikasi lain maka Anda tidak bisa melakukannya. Tutup saja file di Word.
Kristopher
@FrenkyB Bisakah Anda melakukan File.Copy? Saya menemukan itu berfungsi, kemudian membaca dari file itu ke dalam aliran dan menghapus file baru ... mengerikan, tetapi tampaknya berhasil.
ridecar2
3
Saya menggunakan Kontrol Panel untuk menambahkan gambar atau bahkan streaming video, tetapi Anda dapat menyimpan gambar di SQL Server sebagai Gambar atau MySQL sebagai largeblob . Kode ini banyak bekerja untuk saya. Saksikan berikut ini.
Di sini Anda menyimpan gambar
MemoryStream ms =newMemoryStream();Bitmap bmp =newBitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);// here you can change the Image formatbyte[]Pic_arr=newbyte[ms.Length];
ms.Position=0;
ms.Read(Pic_arr,0,Pic_arr.Length);
ms.Close();
Dan di sini Anda dapat memuat, tetapi saya menggunakan Kontrol PictureBox.
MemoryStream ms =newMemoryStream(picarr);
ms.Seek(0,SeekOrigin.Begin);
fotos.pictureBox1.Image=System.Drawing.Image.FromStream(ms);
MemoryStream
?Jawaban:
Anda dapat menggunakan
MemoryStream.WriteTo
atauStream.CopyTo
(didukung dalam kerangka versi 4.5.2, 4.5.1, 4.5, 4) metode untuk menulis konten aliran memori ke aliran lain.Memperbarui:
sumber
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
sebelumCopyTo
akan mengatur posisi saat ini ke 0, sehinggaCopyTo
akan menyalin aliran lengkap.Dengan asumsi nama MemoryStream adalah
ms
.Kode ini menuliskan MemoryStream ke file:
dan ini membaca file ke MemoryStream:
Di .Net Framework 4+, Anda cukup menyalin FileStream ke MemoryStream dan membalikkannya sesederhana ini:
Dan Reverse (MemoryStream ke FileStream):
sumber
ms.ToArray()
fungsi bawaan.using (...){ }
memiliki efek yang persis sama.Aliran harus benar-benar dibuang meskipun ada pengecualian (sangat mungkin pada file I / O) - menggunakan klausa adalah pendekatan favorit saya untuk ini, jadi untuk menulis MemoryStream Anda, Anda dapat menggunakan:
Dan untuk membacanya kembali:
Jika file berukuran besar, maka perlu dicatat bahwa operasi membaca akan menggunakan memori dua kali lebih banyak dari total ukuran file . Salah satu solusi untuk itu adalah membuat MemoryStream dari array byte - kode berikut mengasumsikan Anda tidak akan menulis ke aliran itu.
Penelitian saya (di bawah) menunjukkan bahwa buffer internal adalah array byte yang sama dengan yang Anda lewati, sehingga seharusnya menghemat memori.
sumber
Bagi siapa pun yang mencari versi pendek:
sumber
Jawaban gabungan untuk menulis ke file dapat berupa;
sumber
Simpan ke dalam file
Muat dari file
dimana
dan
sumber
Untuk memuat file, saya suka ini jauh lebih baik
sumber
Saya menggunakan Kontrol Panel untuk menambahkan gambar atau bahkan streaming video, tetapi Anda dapat menyimpan gambar di SQL Server sebagai Gambar atau MySQL sebagai largeblob . Kode ini banyak bekerja untuk saya. Saksikan berikut ini.
Di sini Anda menyimpan gambar
Dan di sini Anda dapat memuat, tetapi saya menggunakan Kontrol PictureBox.
Semoga bisa membantu.
sumber
Penggunaan: -
sumber