Сохранение двоичных данных в потоках - PullRequest
1 голос
/ 12 декабря 2010

Используя 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 ]

4 голосов
/ 12 декабря 2010

Использование 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);
}
3 голосов
/ 12 декабря 2010

Вы можете позвонить WebClient.DownloadFile(url, localPath).

В .Net 4.0 вы можете упростить свой текущий код, позвонив Stream.CopyTo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...