Kaip išsaugoti srautą į C # failą?

Turiu „ StreamReader objektą, kurį inicijuoju sraute, dabar noriu išsaugoti šį srautą į diską (srautas gali būti .gif arba .jpg arba .pdf ).

Esamas kodas:

 StreamReader sr = new StreamReader(myOtherObject.InputStream); 
  • Man reikia jį įrašyti į diską (turiu failo pavadinimą).
  • Ateityje galbūt norėčiau tai išsaugoti „SQL Server“.

Aš taip pat turiu kodavimo tipą, kurio reikia, jei jį įrašysiu į SQL Server, ar ne?

615
04 янв. „Loadman“ nustatė sausio 04 d 2009-01-04 23:04 '09 at 23:04 2009-01-04 23:04
@ 10 atsakymų

Kaip nurodyta „Tilendor“ atsakymuose „Jon Skeet“, srautai turi „ CopyTo metodą su .NET 4.

 var fileStream = File.Create("C:\\Path\\To\\File"); myOtherObject.InputStream.Seek(0, SeekOrigin.Begin); myOtherObject.InputStream.CopyTo(fileStream); fileStream.Close(); 

Arba using sintaksę:

 using (var fileStream = File.Create("C:\\Path\\To\\File")) { myOtherObject.InputStream.Seek(0, SeekOrigin.Begin); myOtherObject.InputStream.CopyTo(fileStream); } 
797
01 апр. Atsakymą pateikė Antoine Leclair balandžio 1 d. 2011-04-01 19:01 '11, 19:01, 2011-04-01 19:01

Jūs neturėtumėte naudoti „ StreamReader “ dvejetainiams failams (pvz., Gif arba jpg). StreamReader - teksto duomenims. Beveik neabejotinai neteksite duomenų, jei jį naudosite savavališkai. (Jei naudojate kodavimą. GetEncoding (28591), tikriausiai bus gerai, bet kas?)

Kodėl jums reikia naudoti StreamReader ? Kodėl tiesiog įrašytumėte dvejetainius duomenis kaip dvejetainius duomenis ir įrašykite juos į disko (arba SQL) kaip dvejetainius duomenis?

Redaguoti: nes būtent tai nori žmonės ... jei norite tiesiog nukopijuoti vieną srautą į kitą (pvz., Į failą), naudokite kažką panašaus:

 /// <summary> /// Copies the contents of input to output. Doesn't close either stream. /// </summary> public static void CopyStream(Stream input, Stream output) { byte[] buffer = new byte[8 * 1024]; int len; while ( (len = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, len); } } 
border=0

Jei norite naudoti srautą į failą, pvz .:

 using (Stream file = File.Create(filename)) { CopyStream(input, file); } 

Atkreipkite dėmesį, kad „ Stream.CopyTo buvo įvestas .NET 4, kuris iš esmės yra tas pats tikslas.

482
04 янв. Atsakymą pateikė Jonas Skeet 04 sausis 2009-01-04 23:08 '09 23:08 2009-01-04 23:08
 public void CopyStream(Stream stream, string destPath) { using (var fileStream = new FileStream(destPath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(fileStream); } } 
61
01 авг. atsakymą pateikė Darren Corbett 01 rug. 2013-08-01 23:25 '13, 23:25, 2013-08-01 23:25
 private void SaveFileStream(String path, Stream stream) { var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write); stream.CopyTo(fileStream); fileStream.Dispose(); } 
20
11 дек. Jhonjairoroa87 atsakymas 11 d. 2013-12-11 17:38 '13, 17:38, 2013-12-11 17:38
 //If you don't have .Net 4.0 :) public void SaveStreamToFile(Stream stream, string filename) { using(Stream destination = File.Create(filename)) Write(stream, destination); } //Typically I implement this Write method as a Stream extension method. //The framework handles buffering. public void Write(Stream from, Stream to) { for(int a = from.ReadByte(); a != -1; a = from.ReadByte()) to.WriteByte( (byte) a ); }  
8
07 июля '11 в 17:30 2011-07-07 17:30 atsakymą pateikė George 07 liepos 11 d. 17:30. 2011-07-07 17:30

Negaliu gauti visų atsakymų naudojant „ CopyTo , kur galbūt sistemos, naudojančios programą, gali būti neatnaujintos .NET 4. 0+. Žinau, kad kai kurie norėtų, kad žmonės būtų atnaujinami, tačiau suderinamumas taip pat yra geras.

Antra, nenaudojau srauto, kad galėčiau nukopijuoti iš kito srauto. Kodėl gi ne tik:

 byte[] bytes = myOtherObject.InputStream.ToArray(); 

Gavę baitus, galite lengvai juos įrašyti į failą:

 public static void WriteFile(string fileName, byte[] bytes) { string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (!path.EndsWith(@"\")) path += @"\"; if (File.Exists(Path.Combine(path, fileName))) File.Delete(Path.Combine(path, fileName)); using (FileStream fs = new FileStream(Path.Combine(path, fileName), FileMode.CreateNew, FileAccess.Write)) { fs.Write(bytes, 0, (int)bytes.Length); //fs.Close(); } } 

Šis kodas veikia taip, kaip aš jį išbandžiau .jpg faile, nors pripažįstu, kad jį naudoju tik su mažais failais (mažiau nei 1 MB). Vienas srautas, be kopijavimo tarp siūlų, be kodavimo, tiesiog užrašykite baitus! Negalima pernelyg apsunkinti StreamReader jei jau turite srautą, kurį galite konvertuoti į bytes tiesiogiai .ToArray() !

Vienintelis potencialus trūkumas, kurį matau, yra tai, kad jei turite didelį failą, kuris turi jį kaip srautą ir naudoja .CopyTo() arba lygiavertį, tai leidžia FileStream perkelti, o ne naudoti baitų masyvą ir nuskaityti baitus po vieną. vienas Tokiu būdu tai gali būti lėčiau. Bet tai neturėtų užspringti, nes FileStream .Write() rašys .Write() tvarko baitų rašymą, ir tai atlieka tik vieną baitą vienu metu, todėl ji neužkimš atminties, išskyrus tai, kad turėsite pakankamai atminties , kad turėtumėte pakankamai atminties, kad srautas būtų objekto byte[] . Mano situacijoje, kai ją panaudojau „ OracleBlob gauti, turėjau eiti į byte[] , jis buvo pakankamai mažas, be to, aš ne srautas, todėl aš tiesiog nusiųstavau savo funkcijos baitus.

Kitas variantas, kuris naudoja srautą, yra naudoti jį su „Jon Skeet CopyStream funkcija, kuri buvo kitame pranešime - ji tiesiog naudoja „ FileStream kad gautų įvesties srautą ir tiesiogiai sukurtų failą iš jo. Jis nenaudoja File.Create , nes jis (iš pradžių man atrodė problemiškas, bet vėliau paaiškėjo, kad tai greičiausiai yra klaida VS ...).

 /// <summary> /// Copies the contents of input to output. Doesn't close either stream. /// </summary> public static void CopyStream(Stream input, Stream output) { byte[] buffer = new byte[8 * 1024]; int len; while ( (len = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, len); } } public static void WriteFile(string fileName, Stream inputStream) { string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (!path.EndsWith(@"\")) path += @"\"; if (File.Exists(Path.Combine(path, fileName))) File.Delete(Path.Combine(path, fileName)); using (FileStream fs = new FileStream(Path.Combine(path, fileName), FileMode.CreateNew, FileAccess.Write) { CopyStream(inputStream, fs); } inputStream.Close(); inputStream.Flush(); } 
7
12 окт. atsakymą pateikė vapcguy spalio 12 d 2016-10-12 16:57 '16, 16:57 pm 2016-10-12 16:57

Kodėl ne naudoti „FileStream“ objektą?

 public void SaveStreamToFile(string fileFullPath, Stream stream) { if (stream.Length == 0) return; // Create a FileStream object to write a stream to a file using (FileStream fileStream = System.IO.File.Create(fileFullPath, (int)stream.Length)) { // Fill the bytes[] array with the stream data byte[] bytesInStream = new byte[stream.Length]; stream.Read(bytesInStream, 0, (int)bytesInStream.Length); // Use FileStream object to write to the specified file fileStream.Write(bytesInStream, 0, bytesInStream.Length); } } 
5
24 апр. atsakymą pateikė Adrianas balandžio 24 d. 2010-04-24 01:49 '10 ne 1:49 2010-04-24 01:49
 public void testdownload(stream input) { byte[] buffer = new byte[16345]; using (FileStream fs = new FileStream(this.FullLocalFilePath, FileMode.Create, FileAccess.Write, FileShare.None)) { int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { fs.Write(buffer, 0, read); } } } 
4
16 июля '13 в 9:47 2013-07-16 09:47 atsakymą davė Angelo liepos 16 d. 13 val. 9:47 2013-07-16 09:47

Kita galimybė - perduoti srautą į byte[] ir naudoti File.WriteAllBytes . Tai turėtų daryti:

 using (var stream = new MemoryStream()) { input.CopyTo(stream); File.WriteAllBytes(file, stream.ToArray()); } 

Apvyniojimas į išplėtimo būdą suteikia geresnį pavadinimą:

 public void WriteTo(this Stream input, string file) { //your fav write method: using (var stream = File.Create(file)) { input.CopyTo(stream); } //or using (var stream = new MemoryStream()) { input.CopyTo(stream); File.WriteAllBytes(file, stream.ToArray()); } //whatever that fits. } 
3
13 февр. Atsakymas pateikiamas nawfal 13 Feb. 2014-02-13 14:04 '14, 14:04 2014-02-13 14:04

public void SaveStreamToFile(string fileFullPath, Stream stream) { File.WriteAllBytes(fileFullPath, stream.ToArray()); }

0
08 дек. Atsakymą pateikė Amir Reza. 2018-12-08 12:49 '18, 12:49 PM 2018-12-08 12:49

Kiti klausimai apie žymes arba Užduoti klausimą