스트림을 C #으로 파일에 저장하려면 어떻게합니까?
StreamReader
스트림으로 초기화 한 개체가 있습니다. 이제이 스트림을 디스크에 저장하려고합니다 (스트림은 .gif
또는 .jpg
또는 일 수 있음 .pdf
).
기존 코드 :
StreamReader sr = new StreamReader(myOtherObject.InputStream);
- 이 파일을 디스크에 저장해야합니다 (파일 이름이 있습니다).
- 나중에 이것을 SQL Server에 저장하고 싶을 것입니다.
SQL Server에 저장하는 경우 필요한 인코딩 유형도 있습니다. 맞습니까?
Jon Skeet의 답변에서 Tilendor가 강조했듯이 스트림에는 CopyTo
.NET 4부터 메서드 가 있습니다 .
var fileStream = File.Create("C:\\Path\\To\\File");
myOtherObject.InputStream.Seek(0, SeekOrigin.Begin);
myOtherObject.InputStream.CopyTo(fileStream);
fileStream.Close();
또는 using
구문 :
using (var fileStream = File.Create("C:\\Path\\To\\File"))
{
myOtherObject.InputStream.Seek(0, SeekOrigin.Begin);
myOtherObject.InputStream.CopyTo(fileStream);
}
당신은 안 사용 StreamReader
(GIF를 또는 JPG를 같은) 바이너리 파일. StreamReader
을위한 텍스트 데이터입니다. 임의의 바이너리 데이터에 사용하면 거의 확실하게 데이터가 손실됩니다. (Encoding.GetEncoding (28591)을 사용한다면 아마 괜찮을 것입니다.하지만 요점은 무엇입니까?)
왜 A를 사용해야 StreamReader
합니까? 바이너리 데이터 를 바이너리 데이터 로 유지하고 디스크 (또는 SQL)에 바이너리 데이터로 다시 쓰지 않는 이유는 무엇 입니까?
편집 : 이것은 당신이 경우에 ... 사람들이보고 싶은 것을 보인다으로 않는 그냥이 같은 사용 무언가 (파일로 예를 들어) 다른 하나 개의 스트림을 복사하려면 :
/// <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);
}
}
이를 사용하여 스트림을 파일로 덤프하려면 다음과 같이하십시오.
using (Stream file = File.Create(filename))
{
CopyStream(input, file);
}
참고 Stream.CopyTo
기본적으로 같은 목적을 제공, .NET 4 년에 도입되었다.
public void CopyStream(Stream stream, string destPath)
{
using (var fileStream = new FileStream(destPath, FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
}
private void SaveFileStream(String path, Stream stream)
{
var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write);
stream.CopyTo(fileStream);
fileStream.Dispose();
}
I don't get all of the answers using CopyTo
, where maybe the systems using the app might not have been upgraded to .NET 4.0+. I know some would like to force people to upgrade, but compatibility is also nice, too.
Another thing, I don't get using a stream to copy from another stream in the first place. Why not just do:
byte[] bytes = myOtherObject.InputStream.ToArray();
Once you have the bytes, you can easily write them to a file:
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();
}
}
This code works as I've tested it with a .jpg
file, though I admit I have only used it with small files (less than 1 MB). One stream, no copying between streams, no encoding needed, just write the bytes! No need to over-complicate things with StreamReader
if you already have a stream you can convert to bytes
directly with .ToArray()
!
Only potential downsides I can see in doing it this way is if there's a large file you have, having it as a stream and using .CopyTo()
or equivalent allows FileStream
to stream it instead of using a byte array and reading the bytes one by one. It might be slower doing it this way, as a result. But it shouldn't choke since the .Write()
method of the FileStream
handles writing the bytes, and it's only doing it one byte at a time, so it won't clog memory, except that you will have to have enough memory to hold the stream as a byte[]
object. In my situation where I used this, getting an OracleBlob
, I had to go to a byte[]
, it was small enough, and besides, there was no streaming available to me, anyway, so I just sent my bytes to my function, above.
Another option, using a stream, would be to use it with Jon Skeet's CopyStream
function that was in another post - this just uses FileStream
to take the input stream and create the file from it directly. It does not use File.Create
, like he did (which initially seemed to be problematic for me, but later found it was likely just a VS bug...).
/// <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();
}
//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, "\n" vs. "\r\n") depending on the StreamReader instance
CurrentEncoding.
*/
Another option is to get the stream to a byte[]
and use File.WriteAllBytes
. This should do:
using (var stream = new MemoryStream())
{
input.CopyTo(stream);
File.WriteAllBytes(file, stream.ToArray());
}
Wrapping it in an extension method gives it better naming:
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.
}
Why not use a FileStream object?
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);
}
}
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);
}
}
}
참고URL : https://stackoverflow.com/questions/411592/how-do-i-save-a-stream-to-a-file-in-c
'your programing' 카테고리의 다른 글
새 Android 조각을 인스턴스화하는 모범 사례 (0) | 2020.09.30 |
---|---|
AMD 프로세서로 AVD를 시작하는 중 오류 (0) | 2020.09.30 |
Amazon Ec2 인스턴스에 SSH 시도-권한 오류 (0) | 2020.09.30 |
[]이 list ()보다 빠른 이유는 무엇입니까? (0) | 2020.09.30 |
xkcd 스타일 그래프를 어떻게 만들 수 있습니까? (0) | 2020.09.30 |