Какой самый быстрый способ вывести большой объем данных? - PullRequest
1 голос
/ 08 марта 2011

У меня есть веб-сервис JAX-RS, который вызывает базу данных db2 z / os и возвращает около 240 МБ данных в наборе результатов. Затем я создаю OutputStream для отправки этих данных клиенту, просматривая набор результатов и добавляя несколько тегов XML для моего вывода.

Я не совсем понимаю, что использовать PrintWriter, BufferedWriter или OutputStreamWriter. Я ищу самый быстрый способ доставки данных. Я также не хочу, чтобы JVM удерживала эти данные дольше, чем нужно, поэтому я не использую их память.

Любая помощь приветствуется.

Ответы [ 5 ]

1 голос
/ 08 марта 2011

Одним из решений (которое может не работать для вас) является создание задания / потока, который создает файл, а затем уведомляет пользователя, когда файл готов к загрузке, таким образом, вы не привязаны к пропускной способностиподключение к клиенту (и вы даже можете сжать файл должным образом, прежде чем клиент загрузит его)

Некоторые приложения Business Intelligence и анализирующие данные делают это, особенно если процесс генерирует данные некоторое время.

1 голос
/ 08 марта 2011

Вы должны использовать

  1. BufferedWriter
  2. Часто вызывать .flush ()
  3. Включить gzip для лучшего сжатия
  4. Начать думать о другом способе сделать это.Могут ли ваши данные быть разбиты на страницы?Нужны ли вам все данные в одном запросе?
1 голос
/ 08 марта 2011

Если вы отправляете большие двоичные данные, вы, вероятно, не хотите использовать xml. При использовании xml двоичные данные обычно представляются с использованием base64, который становится больше исходного двоичного файла и использует довольно много ЦП для преобразования в base64.

На вашем месте я бы отправил двоичный файл отдельно от xml. Если вы используете WebService, вложение MTOM может помочь. В противном случае вы можете отправить ссылку на двоичные данные в XML и запустить приложение. скачать двоичные данные отдельно.

Что касается самого быстрого способа отправки бинарного файла, если вы используете weblogic, достаточно просто написать на выходной трамвай ответа. Этот выходной поток, скорее всего, буферизуется, и что бы вы ни делали, в любом случае производительность не изменится.

Включение gzip также может помочь в зависимости от того, что вы отправляете (например, если вы отправляете jpeg (материал, который уже сжат)) или что-то еще, это не очень поможет, но если вы отправляете необработанный текст, то это может помочь много и т. д.).

0 голосов
/ 08 марта 2011

Вы никогда не должны использовать PrintWriter для вывода данных по сети. Прежде всего, это создает зависимые от платформы разрывы строк. Во-вторых, он молча перехватывает все исключения ввода-вывода, что затрудняет вам работу с этими исключениями.

И если вы отправляете 240 МБ в виде XML, то вы определенно делаете что-то не так. Прежде чем начать беспокоиться о том, какой класс потока использовать, попробуйте уменьшить объем данных.

РЕДАКТИРОВАТЬ:

Совет относительно PrintWriter (и PrintStream) пришел из книги Эллиотта Расти Гарольда . Я не могу вспомнить, какой именно, но это было несколько лет назад. Я думаю, что ServletResponse.getWriter () был добавлен в API после того, как была написана эта книга - так что похоже, что Sun не последовала совету Расти. Я все еще думаю, что это был хороший совет - по причинам, изложенным выше, и потому, что это может соблазнить авторов реализации на нарушение контракта API чтобы получить предсказуемое поведение.

0 голосов
/ 08 марта 2011

Максимальная скорость вывода будет ограничена пропускной способностью сети, и я уверен, что любой Java OutputStream будет намного быстрее, чем вы заметите разницу.

Выбор зависит от данных, которые нужно отправить: текст (строки) PrintWriter прост, что байтовый массив принимает OutputStream.

Чтобы хранить не слишком много данных в буферах, вы должны вызывать flush () любой x kb, возможно.

...