2010-02-02 23 views
6

Un usuario carga un archivo grande en mi sitio web y quiero descomprimirlo y almacenarlo en un blob. Así que tengo un InputStream descomprimido y el blob quiere un InputStream. Sé cómo comprimir un InputStream a un Outputstream usando GZIPOutputStream, pero ¿cómo puedo pasar de la salida OutputStream gzip a la entrada requerida por el blob?¿Cómo puedo convertir un InputStream sin comprimir en un InputStream gzip'ed de manera eficiente?

La única forma que pude encontrar es utilizar ByteArrayOutputStream y luego crear un nuevo InputStream usando toByteArray. Pero eso significará que tengo una copia completa del archivo en la memoria. Y no me sorprendería si la implementación del controlador JDBC convirtiera la transmisión en un byte [] también, así tendría dos copias en la memoria.

+0

Si no quiere el archivo completo en la memoria, escriba en un archivo. De la forma en que lo veo, los datos de gzip necesitan ir a alguna parte. –

+0

Tenía la esperanza de transmitir directamente en el blob, así que nunca tuve que tener todo en la memoria. Parece que eso no funcionará, ya que necesito saber la longitud en el momento en que configuro el parámetro blob. Supongo que técnicamente, podría transmitir a un archivo, obtener el tamaño del archivo, y luego usarlo como un flujo de entrada en el blob para que nunca tenga que mantener todo en la memoria. En este caso, esencialmente usaría el sistema de archivos como mi memoria, lo que podría terminar siendo útil. –

Respuesta

4

Si está en Java 1.6 puede usar java.util.zip.DeflaterInputStream. Por lo que puedo decir, esto hace exactamente lo que quieres. Si no puede usar 1.6, debe poder volver a implementar DeflaterInputStream usando java.util.zip.Deflater. Al leer los datos del BLOB, utilice un InflaterInputStream como filtro para recuperar los datos originales.

+0

No tenía conocimiento de esa Clase. Esa parece la solución correcta. Desafortunadamente, la implementación de Blob usa la longitud y DeflaterInputStream siempre devuelve 0 o 1. Creo que el hecho de que necesite la longitud significa que no voy a poder comprimir y transmitir los datos directamente al blob, pase lo que pase, ya que el no se puede conocer la longitud hasta que se complete la compresión. –

+0

@Brian ¿Necesita pasar una longitud junto con el flujo de entrada al crear el blob? No hay método de longitud en InputStream, solo un método disponible que significa algo totalmente diferente de la longitud de la secuencia. –

+0

disponible() parece devolver la longitud correcta en la secuencia de entrada original (que proviene de una publicación HTTP). Tal vez se basa en la duración del contenido o tal vez en realidad está leyendo todo el flujo en algún lugar antes de que lo obtenga. Pero eso no ayuda una vez que lo comprime, porque no sabré el tamaño comprimido hasta que ya haya procesado todo el flujo, en ese punto está en la memoria así que también puedo convertirlo en un byte []. –

Cuestiones relacionadas