2010-07-02 3 views
0

Я хотел бы грубо отслеживать ход загрузки файла. Я знаю, что я могу переопределить MultipartEntity и сделать метод writeTo (OutputStream out) записывать в класс FilterOutputStream, который я создал, чтобы обернуть значение InputStream по умолчанию. Для получения полной информации о том, как я это сделал, см. Мой ответ here.Как правильно расширить класс Java FilterOutputStream?

Однако при ближайшем рассмотрении это подсчет каждого байта отправляется дважды! Я пошел в документацию, чтобы узнать, что случилось. Похож, что метод метода FilterOutputStream просто вызывает метод write (byte) метода FilterOutputStream в цикле. Он рекомендует подклассы предоставлять более эффективный метод. Я бы предположил, что это связано с вызовом основной записи OutputStream (byte [], int, int) и надеется, что базовый OutputStream имеет лучший метод нажатия байтов в поток (рекомендуемые doc подклассы OutputStream переопределяют этот метод и выполняют лучшую работу чем просто цикл по методу WriteStream # write (byte)).

Здесь я нахожусь в затруднительном положении. Я не могу гарантировать, что MultipartEntity # writeTo (OutputStream) всегда приведет к вызову OutputStream.write (byte [], int, int), поэтому, если я посчитаю отправленные там байты, я могу пропустить некоторые, которые отправляются с использованием метод write (byte). Тем не менее, я не могу рассчитывать на метод write (byte), потому что метод OutputStream.write (byte [], int, int) никогда не может вызвать метод write (byte).

Один ответ - вызвать super.write (byte [], int, int) внутри метода write (byte [], int, int) моего подкласса. Затем я знаю, что это будет просто цикл по методу write (byte), записывая по одному байту за раз. Затем я могу подсчитать все байты, написанные внутри метода write (byte). Однако это неэффективно, и документы напрямую рекомендуют против него. Я уверен, что некоторым подклассам OutputStream удалось написать сразу несколько байтов в поток, поэтому глупо не использовать это преимущество.

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

Извините, если это долго, я сделал это вики в случае, если кто может описать проблему лучше, чем я

+0

http://www.karlin.mff.cuni.cz/network/prirucky/javatut/java/io/writingFiltered.html – Val

ответ

3

Просто позвоните write(byte[] b, int off, int len) на основной поток, когда тот же метод вызывается на вашем потоке счета. Это никогда не вызовет метод write(byte b) в потоке подсчета.

Кроме того, ваш CountingOutputStream в связанном ответе имеет ряд других проблем.

  1. Она имеет свою собственную ссылку на обернутом выходной поток, даже если FilterOutputStream магазинов, что для вас в защищенной области, называемой out.
  2. Он записывает len байты в обернутый поток, когда вызывается write(byte[] b, int off, int len), но только добавляет 1 к количеству переданных байтов.
  3. Он не увеличивает байты, переданные в write(byte b).
+0

Colin, спасибо большое! Это делает его намного понятнее :) – Hamy

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