2010-12-12 2 views
1

Используя C#, я был удивлен, как сложно было сохранить двоичную информацию из потока. Я пытаюсь загрузить файл данных PNG с использованием класса WebRequest, но просто перенос полученного потока в файл, без развращения, был более подробным, чем я думал. Во-первых, просто использование StreamReader и StreamWriter не помогло, так как функция ReadToEnd() возвращает строку, которая эффектно удваивает размер файла PNG (вероятно, из-за преобразования UTF)Сохранение двоичных данных в потоках

Итак, мой вопрос: действительно ли у меня есть написать весь этот код, или есть более чистый способ сделать это?

  Stream srBytes = webResponse.GetResponseStream(); 
      // Write to file 
      Stream swBytes = new FileStream("map(" + i.ToString() + ").png",FileMode.Create,FileAccess.Write); 
      int count = 0; 
      byte[] buffer = new byte[4096]; 
      do 
      { 
       count = srBytes.Read(buffer, 0, buffer.Length); 
       swBytes.Write(buffer, 0, count); 
      } 
      while (count != 0); 
      swBytes.Close(); 
+2

вы никогда не должны рассматривать произвольные потоки байтов, как строки. Так как это не так. – Joey

ответ

4

Использование StreamReader/StreamWriter определенно является ошибкой, да - потому что это попытка загрузить файл как текст, а это не так.

Варианты:

  • Использование WebClient.DownloadFile в качестве SLaks предложил
  • В .NET 4, используйте Stream.CopyTo(Stream) для копирования данных во многом таким же образом, как вы сюда попали
  • В противном случае, написать свой собственный метод утилиты для копирования, тогда вам нужно сделать это только один раз; вы могли бы даже написать это как метод расширения, что означает, что при обновлении до .NET 4 вы можете просто избавиться от метода полезности и использовать встроенный в одном, без изменения кода вызова:

    public static class StreamExtensions 
    { 
        public static void CopyTo(this Stream source, Stream destination) 
        { 
         if (source == null) 
         { 
          throw new ArgumentNullException("source"); 
         } 
         if (destination == null) 
         { 
          throw new ArgumentNullException("destination"); 
         } 
         byte[] buffer = new byte[8192]; 
         int bytesRead; 
         while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) 
         { 
          destination.Write(buffer, 0, bytesRead); 
         } 
        } 
    } 
    

Обратите внимание, что вы должны использовать using заявления для веб-ответ, поток ответа и выходной поток для того, чтобы убедиться, что они всегда закрыты надлежащим образом, как это:

using (WebResponse response = request.GetResponse()) 
using (Stream responseStream = response.GetResponseStream()) 
using (Stream outputStream = File.OpenWrite("map(" + i + ").png")) 
{ 
    responseStream.CopyTo(outputStream); 
} 
+1

Skiiilz :) Спасибо –

Смежные вопросы