2010-02-02 3 views
6

Пользователь загружает большой файл на мой сайт, и я хочу gzip файл и сохранить его в блобе. Таким образом, у меня есть несжатый InputStream, и blob хочет InputStream. Я знаю, как сжимать InputStream к выходному потоку с помощью GZIPOutputStream, но как мне перейти с gzip'ed OutputStream обратно в InputStream, необходимый блобу.Как можно эффективно преобразовать несжатый InputStream в gzip'ed InputStream?

Единственный способ, которым я мог найти, - использовать ByteArrayOutputStream, а затем создать новый InputStream, используя toByteArray. Но это будет означать, что у меня есть полная копия файла в памяти. И меня не удивило бы, если бы реализация драйвера JDBC конвертировала поток в байт [], так что у меня было бы две копии в памяти.

+0

Если вы не хотите, чтобы весь файл в памяти записывался в файл. Как я вижу, данные gzip'd должны куда-то идти. –

+0

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

ответ

4

Если вы используете java 1.6, вы можете использовать java.util.zip.DeflaterInputStream. Насколько я могу судить, это делает именно то, что вы хотите. Если вы не можете использовать 1.6, вы должны иметь возможность переопределить DeflaterInputStream, используя java.util.zip.Deflater. При чтении данных из BLOB используйте InflaterInputStream в качестве фильтра, чтобы вернуть исходные данные.

+0

Я не знал этого класса. Это похоже на правильное решение. К сожалению, реализация Blob использует длину, и DeflaterInputStream всегда возвращает 0 или 1. Я думаю, что тот факт, что мне нужна длина, означает, что я не буду иметь возможность сжимать и передавать данные непосредственно в блоб независимо от того, что длина не может быть известна до завершения компрессии. –

+0

@Brian Итак, вам нужно передать длину вместе с входным потоком при создании blob? В InputStream нет метода длины, только доступный метод, который означает нечто совершенно отличное от длины потока. –

+0

Доступно(), кажется, возвращает правильную длину исходного потока ввода (который исходит из сообщения http). Возможно, он основан на длине контента или, возможно, на самом деле читает весь поток где-то вверх по течению, прежде чем я его получу. Но это не помогает, когда я сжимаю его, потому что я не буду знать сжатый размер, пока я уже не обработал весь поток, и в какой момент он находится в памяти, поэтому я могу преобразовать его в байт []. –

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