Jeśli chcesz zapisać w pliku, dlaczego używasz MemoryStream?
Oded
@Oded Czego powinienem użyć? Czy możesz podać mi przykład?
Mahdi Ghiasi
Odpowiedzi:
365
Możesz użyć MemoryStream.WriteTolub Stream.CopyTo(obsługiwanych w frameworku wersji 4.5.2, 4.5.1, 4.5, 4) metod do zapisania zawartości strumienia pamięci do innego strumienia.
memoryStream.CopyTo nie działało dla mnie, podczas gdy WriteTo działało. Myślę, że może dlatego, że mój memoryStream.Position nie był 0
Mark Adamson
10
Tak to jest poprawne. Różnica między nimi polega na tym, że CopyTo kopiuje z dowolnej aktualnej pozycji zamiast zawsze od początku, jak robi to 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();}
i to czyta plik do 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);}
W .Net Framework 4+ możesz po prostu skopiować FileStream do MemoryStream i odwrócić tak proste:
MemoryStream ms =newMemoryStream();
using (FileStream file =newFileStream("file.bin",FileMode.Open,FileAccess.Read))
file.CopyTo(ms);
I do tyłu (MemoryStream do FileStream):
using (FileStream file =newFileStream("file.bin",FileMode.Create,System.IO.FileAccess.Write))
ms.CopyTo(file);
Czy mogę zapytać, dlaczego używasz FileMode.Create w czytanej próbce vs FileMode.Open?
Philter
6
W pierwszym bloku kodu zamiast ręcznego kopiowania strumienia pamięci do tablicy można użyć funkcji wbudowanej ms.ToArray().
Gman,
5
Ważne jest, aby ustawić pozycjęosition = 0, w przeciwnym razie tablica bajtów (i plik) będzie zawierać wszystkie zera.
Gregory Chrapunowicz
1
@ Fernando68 konstrukcja using (...){ }ma dokładnie taki sam efekt.
Fabricio Araujo
2
Podobnie jak ostrzeżenie dla innych osób „korzystających z (FileStream” i „ms.CopyTo (plik)” ustawia pozycję do końca pliku, a następnie należy zresetować pamięć memorystream.
Rebecca
64
Strumień powinien naprawdę zostać usunięty, nawet jeśli istnieje wyjątek (całkiem prawdopodobne w plikach I / O) - używanie klauzul jest moim ulubionym podejściem do tego, więc do pisania MemoryStream możesz użyć:
using (FileStream file =newFileStream("file.bin",FileMode.Create,FileAccess.Write)){
memoryStream.WriteTo(file);}
I do przeczytania:
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);}
Jeśli pliki są duże, warto zauważyć, że operacja odczytu zużyje dwa razy więcej pamięci niż całkowity rozmiar pliku . Jednym z rozwiązań jest utworzenie MemoryStream z tablicy bajtów - poniższy kod zakłada, że nie będziesz zapisywać do tego strumienia.
MemoryStream ms =newMemoryStream(bytes, writable:false);
Moje badania (poniżej) pokazują, że bufor wewnętrzny jest taką samą tablicą bajtów, jak go przekazujesz, więc powinien oszczędzać pamięć.
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());
Załaduj z pliku
using (var stream =newMemoryStream(System.IO.File.ReadAllBytes(fileName))){Car car =(Car)Serializer.DeserializeFromStream(stream);}
gdzie
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;}}}
Pierwotnie implementacja tej klasy została opublikowana tutaj
Jeśli plik jest otwarty w programie Microsoft Word - czy istnieje sposób na utworzenie strumienia pamięci z tego pliku? Otrzymuję komunikat o błędzie „plik został otwarty przez inny proces”
FrenkyB,
@FrenkyB Ja też często na to wpadam. Jeśli plik jest otwarty w programie Word lub innej aplikacji, nie możesz tego zrobić. Po prostu zamknij plik w programie Word.
Kristopher
@FrenkyB Czy możesz zrobić File.Copy? Przekonałem się, że to działa, a następnie czytam z tego pliku do strumienia i usuwam nowy plik ... okropne, ale wydaje się, że działa.
ridecar2
3
Używam Panelu sterowania, aby dodać obraz lub nawet przesyłać strumieniowo wideo, ale możesz zapisać obraz na SQL Server jako Image lub MySQL jako largeblob . Ten kod działa dla mnie bardzo często. Sprawdź to.
Tutaj zapisz obraz
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();
I tutaj możesz załadować, ale użyłem kontrolki PictureBox.
MemoryStream ms =newMemoryStream(picarr);
ms.Seek(0,SeekOrigin.Begin);
fotos.pictureBox1.Image=System.Drawing.Image.FromStream(ms);
MemoryStream
?Odpowiedzi:
Możesz użyć
MemoryStream.WriteTo
lubStream.CopyTo
(obsługiwanych w frameworku wersji 4.5.2, 4.5.1, 4.5, 4) metod do zapisania zawartości strumienia pamięci do innego strumienia.Aktualizacja:
źródło
[file|memory]Stream.Seek(0, SeekOrigin.Begin);
przedtemCopyTo
spowoduje ustawienie bieżącej pozycji na 0, coCopyTo
spowoduje skopiowanie całego strumienia.Zakładając, że nazwa MemoryStream to
ms
.Ten kod zapisuje MemoryStream do pliku:
i to czyta plik do MemoryStream:
W .Net Framework 4+ możesz po prostu skopiować FileStream do MemoryStream i odwrócić tak proste:
I do tyłu (MemoryStream do FileStream):
źródło
ms.ToArray()
.using (...){ }
ma dokładnie taki sam efekt.Strumień powinien naprawdę zostać usunięty, nawet jeśli istnieje wyjątek (całkiem prawdopodobne w plikach I / O) - używanie klauzul jest moim ulubionym podejściem do tego, więc do pisania MemoryStream możesz użyć:
I do przeczytania:
Jeśli pliki są duże, warto zauważyć, że operacja odczytu zużyje dwa razy więcej pamięci niż całkowity rozmiar pliku . Jednym z rozwiązań jest utworzenie MemoryStream z tablicy bajtów - poniższy kod zakłada, że nie będziesz zapisywać do tego strumienia.
Moje badania (poniżej) pokazują, że bufor wewnętrzny jest taką samą tablicą bajtów, jak go przekazujesz, więc powinien oszczędzać pamięć.
źródło
Dla każdego, kto szuka krótkich wersji:
źródło
Łączna odpowiedź na zapis do pliku może być;
źródło
Zapisz w pliku
Załaduj z pliku
gdzie
i
źródło
Do ładowania pliku bardziej mi się podoba
źródło
Używam Panelu sterowania, aby dodać obraz lub nawet przesyłać strumieniowo wideo, ale możesz zapisać obraz na SQL Server jako Image lub MySQL jako largeblob . Ten kod działa dla mnie bardzo często. Sprawdź to.
Tutaj zapisz obraz
I tutaj możesz załadować, ale użyłem kontrolki PictureBox.
Nadzieja pomaga.
źródło
Stosowanie :-
źródło