How do I save a stream to a file in C#?
我有一个用流初始化的
现有代码:
1 |
我也有编码类型,如果我将其存储到SQL Server,我需要这种类型,对吗?
正如Tilendor在jon skeet的答案中所强调的,streams自.net 4以来有一个
1 2 3 4 | var fileStream = File.Create("C:\\Path\\To\\File"); myOtherObject.InputStream.Seek(0, SeekOrigin.Begin); myOtherObject.InputStream.CopyTo(fileStream); fileStream.Close(); |
或者使用
1 2 3 4 5 | using (var fileStream = File.Create("C:\\Path\\To\\File")) { myOtherObject.InputStream.Seek(0, SeekOrigin.Begin); myOtherObject.InputStream.CopyTo(fileStream); } |
不能将
为什么你需要使用
编辑:这似乎是人们想要看到的…如果您只想将一个流复制到另一个流(例如,复制到一个文件),请使用如下方法:
1 2 3 4 5 6 7 8 9 10 11 12 | /// <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); } } |
要使用它将流转储到文件,例如:
1 2 3 4 | using (Stream file = File.Create(filename)) { CopyStream(input, file); } |
注意,
1 2 3 4 5 6 7 | public void CopyStream(Stream stream, string destPath) { using (var fileStream = new FileStream(destPath, FileMode.Create, FileAccess.Write)) { stream.CopyTo(fileStream); } } |
1 2 3 4 5 6 | private void SaveFileStream(String path, Stream stream) { var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write); stream.CopyTo(fileStream); fileStream.Dispose(); } |
我并没有用
另一件事是,我一开始不会使用流从另一个流复制。为什么不直接做:
1 | byte[] bytes = myOtherObject.InputStream.ToArray(); |
一旦有了字节,就可以轻松地将它们写入文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(); } } |
虽然我承认我只在小文件(小于1 MB)中使用过,但这段代码的工作原理与我用
这样做的唯一潜在缺点是,如果有一个大文件,将其作为流,并使用
另一种选择是,使用流,将它与另一个post中的jon skeet的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /// <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(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | //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 ); } /* Note, StreamReader is an IEnumerable<Char> while Stream is an IEnumbable<byte>. The distinction is significant such as in multiple byte character encodings like Unicode used in .Net where Char is one or more bytes (byte[n]). Also, the resulting translation from IEnumerable<byte> to IEnumerable<Char> can loose bytes or insert them (for example," " vs." ") depending on the StreamReader instance CurrentEncoding. */ |
为什么不使用文件流对象?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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); } } |
另一种选择是将流获取到
1 2 3 4 5 | using (var stream = new MemoryStream()) { input.CopyTo(stream); File.WriteAllBytes(file, stream.ToArray()); } |
将其包装在扩展方法中可以使其更好地命名:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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. } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |