2011-06-03 15 views
5

Tengo bastante cantidad de datos de transmisión (> 100MB), que, por razones de compresión, me gustaría alojar empaquetados en un archivo zip en un servidor http. Entonces, este archivo zip contiene un solo archivo.Java: transmitir el contenido de Zipfile a través de HTTP

¿Es posible que un cliente java pueda transmitir los datos a través de http, a pesar de que está empaquetado en un archivo zip?

Según Wikipedia, cremalleras no son secuencialmente ...

http://en.wikipedia.org/wiki/ZIP_(file_format)#Structure

Si esto sigue siendo posible alguna manera, entonces, ¿cómo?

editar: about gzip: como he dicho, uso un cliente Java personalizado (no un navegador web) ¿gzip está disponible en la implementación http de Java?

+0

Usted' Estamos hablando de la transmisión de los archivos dentro del archivo comprimido individualmente, no del archivo zip completo, ¿verdad? – Alvin

+0

Bueno, en realidad, el archivo zip contiene solo un archivo. y este es el que quiero transmitir. – clamp

Respuesta

4

Java admite el formato gzip con GZipInputStream (descompresión) y GZipOutputStream (compresión). Ambos zip y gzip usan el mismo formato de compresión internamente, la diferencia principal está en los metadatos: zip lo tiene al final del archivo, gzip al principio (y gzip solo admite un archivo adjunto fácilmente).

Para transmitir un archivo grande, usar gzip será lo mejor que puede hacer, incluso más ya que no necesita acceder a los metadatos.

no estoy seguro de si el HTTPConnection envía Accept-Encoding: gzip y luego se encarga de inflar el contenido de forma automática si el servidor lo entrega con Content-Encoding: gzip, pero que sin duda puede hacerlo de forma manual si el servidor simplemente envía un archivo de .gz como tal (es decir, con Content-Encoding: identity).

(Por cierto, asegúrese de leer de la corriente con no demasiado pequeños tampones, ya que cada llamada desinflado tendrá una sobrecarga de llamada nativa, ya que GZIPInputStream de Java utiliza el nativo zlib aplicación.)

2

Sí se puede, transmitir los zip y utilizar el tipo MIME como application/zip

Si realmente quiere tocar música corriente en el otro extremo, entonces no puede ser hecho trivial como pueda solo desempaquetar una vez que todo el zip esté disponible en el cliente.

Si el tamaño es que la preocupación, puede bajar sus formatos velocidad binaria mp3 o uso, tales como OGG/Vorbis

+0

estas seguro, porque esta imagen dice que no es transmisible: http://en.wikipedia.org/wiki/File:ZIPformat.jpg – clamp

+1

@clamp: Puedes transmitirlo, pero no puedes descomprimirlo hasta que recibas todo el contenido del archivo en el lado del cliente. (eso es lo que está describiendo la imagen/el artículo) – sarumont

+0

@sarumont +1 a la derecha –

4

Tendría más sentido dejar que el servidor web hacer la comprimir? Si simplemente está tratando de reducir la cantidad de ancho de banda que se utiliza, en lugar de realmente querer almacenar el archivo comprimido en el servidor, esto podría ser simplemente una cuestión de configuraciones, por ejemplo, ver:

http://tomcat.apache.org/tomcat-5.5-doc/config/http.html

para compresión HTTP/1.1 GZIP. El servidor puede forzar la respuesta al cliente para que se comprima.

Véase también http://en.wikipedia.org/wiki/HTTP_compression.

El cliente recibirá paquetes comprimidos y manejará la descompresión. También debería ser posible transmitir el archivo, por lo que el cliente no necesita todo el archivo antes de poder hacer algo útil, ya que el servidor puede comprimir fragmentos individuales.

+0

Estoy de acuerdo con el punto básico de @ Ant: si tiene un único archivo, use compresión directa en lugar de un archivo zip. El archivo se puede comprimir o no en el servidor, como desee. –

+0

no tienes el problema aquí. Si comprime el archivo, para descomprimirlo en el otro extremo, necesita el archivo zip completo. Por lo tanto, no puede usar los datos del archivo comprimido si están parcialmente en el cliente. Así que, básicamente, a pesar de que el archivo zip se está transmitiendo, el audio no lo está. Creo que la solución es usar una velocidad de bits baja o mejores formatos de transmisión –

+0

@Suraj si los trozos individuales están comprimidos, entonces no, no tienes el problema. pero es cierto que debe verificar lo que sucede si utilizó Transfer-Encoding fragmentado junto con la compresión GZIP. potencialmente, necesitas usar solo la codificación de transferencia fragmentada, y comprimir los fragmentos tú mismo y descomprimirlos en el cliente, lo que es complicado. Realmente no sé exactamente cómo funciona sin probarlo, pero supongo que los trozos individuales serán comprimidos. si alguien lo intenta, házmelo saber! –

5

He aquí un fragmento de código (que funciona) que el cliente puede utilizar para leer de la corriente de cremallera:

static void processZippedInputStream(InputStream in, String entryNameRegex) 
throws IOException 
{ 
    ZipInputStream zin = new ZipInputStream(in); 
    ZipEntry ze; 
    while ((ze = zin.getNextEntry()) != null) 
    { 
     if (ze.getName().matches(entryNameRegex)) 
     { 
      // treat zin as a normal input stream - ie read() from it till "empty" etc 
      break; 
     } 
     zin.closeEntry(); 
    } 
    zin.close(); 
} 

La principal diferencia con un InputStream normal es iteración a través de las entradas. Puede saber, por ejemplo, que desea la primera entrada, por lo que no es necesario el parámetro de coincidencia de nombre, etc.

+0

como dije, el archivo zip solo contendría una sola entrada. sin embargo, parece que la metainformación acerca de esto está al final del archivo zip, por lo que tendría que descargar todo el archivo antes de que pueda comenzar a descomprimir, ¿verdad? – clamp

+0

No - las entradas se encuentran por nombre y contenido, por lo que obtendrá el encabezado de entrada directamente al frente – Bohemian

0

Use GZIP y luego puede transmitir. Gzip usa el algoritmo de compresión predeterminado de zip de todos modos.

+0

gracias, pero ¿este gzip está disponible en la implementación http de java? – clamp

+0

Asegúrese de enviar un gzipstream y en el lado del servidor almacenar la secuencia en el disco. Usted acaba de envolver las transmisiones actuales. El gzipstream es la entidad incluida dentro del POST o PUT – MJB

Cuestiones relacionadas