스트림을 C#의 파일에 저장하려면 어떻게 해야 합니까?
나는 있습니다StreamReader스트림으로 초기화한 개체입니다. 이제 이 스트림을 디스크에 저장합니다(스트림이.gif또는.jpg또는.pdf).
기존 코드:
StreamReader sr = new StreamReader(myOtherObject.InputStream);
- 디스크에 저장해야 합니다(파일 이름이 있습니다).
- 나중에 SQL Server에 저장할 수도 있습니다.
인코딩 유형도 있는데 SQL Server에 저장할 때 필요한 유형이 맞습니까?
에는 존 가 있습니다.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);
}
은 야합다니화에 .Seek아직 시작 단계에 있지 않거나 전체 스트림을 복사하지 않을 경우.
사용하면 안 됩니다.StreamReader이진 파일(예: gifs 또는 jpgs)의 경우. StreamReader텍스트 데이터용입니다.임의 이진 데이터에 데이터를 사용하면 거의 확실하게 데이터가 손실됩니다. (인코딩을 사용하는 경우).GetEncoding(28591)은 아마 괜찮을 것입니다만, 무슨 의미가 있습니까?)
사용해야 하는 이유는 무엇입니까?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);
}
에서 소개된 내용을 참고하십시오.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();
}
다음을 사용하여 일부 답변을 얻지 못했습니다.CopyTo앱을 사용하는 시스템이 로 업그레이드되지 않았을 수 있습니다.NET 4.0 버전.일부는 사람들에게 업그레이드를 강요하고 싶지만 호환성 또한 좋습니다.
다른 하나는 스트림을 사용하여 다른 스트림에서 복사할 수 없다는 것입니다.그냥 하는 게 어때요?
byte[] bytes = myOtherObject.InputStream.ToArray();
바이트가 있으면 파일에 쉽게 쓸 수 있습니다.
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();
}
}
는 제가 이코는제대작로다동니합한으로 합니다..jpg파일, 비록 제가 작은 파일(1MB 미만)에서만 사용했다는 것을 인정합니다.스트림 하나, 스트림 간 복사, 인코딩 필요 없음, 바이트 쓰기!문제를 너무 복잡하게 만들 필요가 없습니다.StreamReader에는 이미스이있경변수있환으로 할 수 .bytes와 .ToArray()!
에서 제가 볼 수 은 큰 입니다. 하는 것입니다..CopyTo()또는 동등한 허용 범위FileStream바이트 배열을 사용하고 바이트를 하나씩 읽는 대신 스트리밍합니다.결과적으로 이런 식으로 하는 것이 더 느릴 수 있습니다.하지만 숨이 막혀서는 안 됩니다..Write()의 방법FileStream에서는 바이트 쓰기를 처리하며 한 번에 1바이트만 수행하므로 스트림을 개체로 저장할 수 있는 충분한 메모리가 있어야 한다는 점을 제외하고는 메모리가 꽉 차지 않습니다.이걸 사용한 내 상황에서, 나는.OracleBlob나는 가야만 했습니다.byte[]그것은 충분히 작았고, 게다가, 어쨌든 내가 사용할 수 있는 스트리밍이 없었기 때문에, 나는 위의 내 기능으로 내 바이트를 보냈습니다.
스트림을 사용하는 또 다른 옵션은 존 스키트와 함께 사용하는 것입니다.CopyStream다른 게시물에 있었던 함수 - 이것은 그냥 사용합니다.FileStream입력 스트림을 가져와서 직접 파일을 만듭니다.를 사용하지 않습니다.File.Create그가 그랬던 것처럼 (처음에는 문제가 있는 것처럼 보였지만 나중에는 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();
}
다음은 일회용 제품의 적절한 사용과 구현을 사용하는 예입니다.
static void WriteToFile(string sourceFile, string destinationfile, bool append = true, int bufferSize = 4096)
{
using (var sourceFileStream = new FileStream(sourceFile, FileMode.OpenOrCreate))
{
using (var destinationFileStream = new FileStream(destinationfile, FileMode.OpenOrCreate))
{
while (sourceFileStream.Position < sourceFileStream.Length)
{
destinationFileStream.WriteByte((byte)sourceFileStream.ReadByte());
}
}
}
}
...그리고 이것도 있습니다.
public static void WriteToFile(Stream stream, string destinationFile, int bufferSize = 4096, FileMode mode = FileMode.OpenOrCreate, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.ReadWrite)
{
using (var destinationFileStream = new FileStream(destinationFile, mode, access, share))
{
while (stream.Position < stream.Length)
{
destinationFileStream.WriteByte((byte)stream.ReadByte());
}
}
}
핵심은 사용(위에 나온 것처럼 일회용을 구현하는 개체의 인스턴스화에서 구현되어야 함)의 적절한 사용 방법을 이해하고 스트림에 대한 속성이 어떻게 작동하는지에 대해 잘 이해하는 것입니다.위치는 문자 그대로 스트림 내의 인덱스(0에서 시작)이며, 각 바이트가 읽기 바이트 방법을 사용하여 읽힐 때 그 뒤를 따릅니다.이 경우에는 기본적으로 for 루프 변수 대신 이 변수를 사용하고 문자 그대로 전체 스트림의 끝 길이(바이트)까지 계속 따라가게 합니다.바이트 단위로 무시하면 실질적으로 동일하기 때문에 모든 것을 깨끗하게 해결하는 이와 같이 간단하고 우아한 것을 얻을 수 있습니다.
또한 ReadByte 메서드는 프로세스에서 바이트를 int에 캐스팅하고 단순히 다시 변환할 수 있습니다.
대량의 과부하를 방지하기 위해 순차적인 데이터 쓰기를 보장하는 동적 버퍼를 만들기 위해 최근 작성한 다른 구현을 추가합니다.
private void StreamBuffer(Stream stream, int buffer)
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
var memoryBuffer = memoryStream.GetBuffer();
for (int i = 0; i < memoryBuffer.Length;)
{
var networkBuffer = new byte[buffer];
for (int j = 0; j < networkBuffer.Length && i < memoryBuffer.Length; j++)
{
networkBuffer[j] = memoryBuffer[i];
i++;
}
//Assuming destination file
destinationFileStream.Write(networkBuffer, 0, networkBuffer.Length);
}
}
}
설명은 매우 간단합니다. 쓰기를 원하는 전체 데이터 세트를 염두에 두어야 하며 특정 양만 쓰기를 원하기 때문에 마지막 매개 변수가 비어 있는 첫 번째 루프를 사용해야 합니다.그런 다음 전달된 내용의 크기로 설정된 바이트 배열 버퍼를 초기화하고 두 번째 루프를 사용하여 j를 버퍼의 크기와 원래의 크기와 비교하여 원래 바이트 배열의 크기보다 크면 실행을 종료합니다.
FileStream 개체를 사용하지 않는 이유는 무엇입니까?
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);
}
}
//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.
*/
을 른다옵스다이것입다니는동하로로 가져오는 입니다.byte[] 및사를 합니다.File.WriteAllBytes이 작업은 다음을 수행해야 합니다.
using (var stream = new MemoryStream())
{
input.CopyTo(stream);
File.WriteAllBytes(file, stream.ToArray());
}
확장 방법으로 래핑하면 더 나은 이름을 지정할 수 있습니다.
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.
}
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
'programing' 카테고리의 다른 글
| 이전 커밋에서 파일 복원 (0) | 2023.05.20 |
|---|---|
| 셸 스크립트에서 문자열이 비어 있지 않거나 공백이 아닌지 확인 (0) | 2023.05.20 |
| POST를 통해 파라미터를 Azure 함수로 전달하는 방법은 무엇입니까? (0) | 2023.05.15 |
| C#은 왜 수학을 실행합니까?Sqrt()가 VB보다 느립니다.NET? (0) | 2023.05.15 |
| mongoose 2개 필드를 사용한 사용자 지정 유효성 검사 (0) | 2023.05.15 |