[C#] C #에서 파일에 스트림을 어떻게 저장합니까?

나는이 StreamReader지금은 디스크에이 스트림을 저장 (스트림이 될 5 월 싶어, 내가 스트림으로 초기화 것을 객체 .gif또는 .jpg.pdf).

기존 코드 :

StreamReader sr = new StreamReader(myOtherObject.InputStream);
  1. 이것을 디스크에 저장해야합니다 (파일 이름이 있습니다).
  2. 앞으로 나는 이것을 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)을 사용하면 괜찮을지 모르지만 요점은 무엇입니까?)

왜 전혀 사용해야 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();
}


답변

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핸들 의 메소드가 한 번에 한 바이트 만 수행하므로 질식 해서는 안되므로 스트림을 a로 유지하기에 충분한 메모리가 있어야byte[] 한다는 것을 제외하고는 메모리를 방해하지 않습니다 . 객체 . 이것을 사용하고을 얻는 상황에서 OracleBlob에 가야했습니다. byte[]충분히 작아서 어쨌든 나에게 사용할 수있는 스트리밍이 없었기 때문에 위의 함수에 바이트를 보냈습니다.

스트림을 사용하는 또 다른 옵션 CopyStream은 다른 게시물에 있던 Jon Skeet의 기능 과 함께 사용 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();
}


답변

//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.
*/


답변

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);
     }
}