2009-08-13 2 views
2

В настоящее время я работаю над программой, которая передает файлы через FTP. Я отправляю файлы в двоичном формате, потому что с ASCII я не могу отправлять специальные символы.Как оптимизировать мой BinaryWriter?

Вот мой код в настоящее время:

using(BinaryReader bReader = new BinaryReader(srcStream)) 
    using (BinaryWriter bWriter = new BinaryWriter(destStream)) 
    { 
     Byte[] readBytes = new Byte[1024]; 
     for(int i = 0; i < bReader.BaseStream.Length; i += 1024) 
     { 
      readBytes = bReader.ReadBytes(1024); 
      bWriter.Write(readBytes); 
     } 
    } 

Мои проблемы с этим кодом являются:

  1. Он работает очень медленно, есть ли способ оптимизировать?
  2. Способ, которым я прошу EOF (EndOfFile), кажется, очень странный, есть ли другой вариант элегантности?

Большое спасибо: D

+0

После внедрения решения размещенного от Джона и Gbegen, я получаю всегда сообщение об ошибке «Запрос не принят». – Camal

ответ

9

Почему вы используете BinaryReader и BinaryWriter вообще? Почему вы неоднократно спрашиваете о длине? Вот метод, я отправил кучу раз в настоящее время:

public static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[8192]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, read); 
    } 
} 

Это использует 8K буфер, но вы можете изменить это очевидно. О, и он повторно использует буфер, а не создает новый массив байтов каждый раз, что и будет делать ваш код :) (Вам не нужно выделять массив байтов, чтобы начать с него - вы могли бы объявить readBytes в точке звонок bReader.ReadBytes.)

+1

Прежде всего, спасибо Jon. Но теперь я очень смущен: D Я довольно новичок в работе с Streams, и я думал, что могу писать только с BinaryWriter в двоичном режиме. Итак, потоки также получили методы чтения/записи. И agian я чему-то научился: D Но на всякий случай, если файл имеет размер «0», но я хочу передать этот файл тоже. Если это работает для меня? – Camal

+0

Это будет нормально работать, да - первый вызов Read вернет 0, и вы выйдете из цикла. BinaryReader/BinaryWriter - это служебные классы для чтения и записи примитивов и т. Д. По потокам. Потоки сами по себе являются просто бинарными источниками и адресами для данных - другая вещь, обычно обернутая вокруг них, - это StreamReader/StreamWriter, которые декодируют/кодируют текст. –

+0

Я все еще хотел бы знать, почему 'BinaryWriter.BaseStream' очень медленный. Разве он не должен возвращать поле потока, которое было сохранено конструктором? –

2

Я думаю, что ваши проблемы с производительностью исходят из двух мест. Вы звоните bReader.BaseStream.Length каждый раз через цикл, и ваш вызов bReader.ReadBytes() каждый раз выделяет новый массив байтов.

Я также не думаю, что BinaryReader и BinaryWriter необходимы, как вы не используете свои возможности для других, чем массивы байтов чтения и записи типов, которые уже поддерживаются в основных потоков через Stream.Read() и Stream.Write().

Я хотел бы сделать это так:

byte [] buffer = new byte[1024]; 
int bytesRead; 
while ((bytesRead = srcStream.Read(buffer, 0, buffer.Length)) != 0) 
{ 
    dstStream.Write(buffer, 0, bytesRead); 
} 
Смежные вопросы