2011-07-14 7 views
7

Estoy tratando de escribir un script ruby ​​fcgi que comprime archivos en un directorio sobre la marcha y envía el resultado en bloque como una respuesta http. Es muy importante que esta compresión se realice como una operación de flujo, de lo contrario, el cliente obtendrá un tiempo de espera para directorios enormes.Ruby zip una secuencia

tengo el siguiente código:

d="/tmp/delivery/" 

# send zip header 
header(MimeTypes::ZIP) 

# pseudocode from here on 
IO.open(d) { |fh| 
    block=fh.readblock(1024) 
    #send zipped block as http response 
    print zip_it(block) 
} 

¿Cómo logro lo que he escrito como pseudo-rubí en el listado superior?

+1

Me gustaría también saber esto, la gema zipruby es tan similar a Java y rígido ... Yo siempre terminan generando la cremallera externa (que es muy potente, pero un poco triste de hacer) – tokland

+0

¿cómo hiciste eso? He intentado con 'IO.popen (" zip -0 -r -o - \ "# {file_list.join ('" "')} \" 2>/dev/null ") {| f | print f.read (512)} 'pero descomprima las notificaciones sobre el formato zip no válido. – gorootde

+0

puede obtener más tracción con tar/gz – rogerdpack

Respuesta

1

La idea de Tokland de usar el comando zip externo funciona bastante bien. Aquí hay un fragmento rápido que debería funcionar con Ruby 1.9 en Linux o entornos similares. Utiliza un parámetro de matriz a popen() para evitar problemas de cotización de shell y sysread/syswrite para evitar el almacenamiento en búfer. Si lo desea, puede mostrar un mensaje de estado en el bloque rescue vacío, o puede usar read y write, aunque no los he probado.

#! usr/bin/env ruby 
d = '/tmp/delivery' 
output = $stdout 
IO.popen(['/usr/bin/zip', '-', d]) do |zip_output| 
    begin 
    while buf = zip_output.sysread(1024) 
     output.syswrite(buf) 
    end 
    rescue EOFError 
    end 
end 
+0

La pregunta se relacionó con la transmisión de un archivo comprimido desde la aplicación web. – Vitalie

1

AFAYK El formato Zip no se puede transmitir, al final de la compresión escribe algo en el encabezado del archivo.

gz o tar.gz es la mejor opción.

+0

¿Cómo se puede hacer eso sin usar un cmd de shell? – gorootde

+1

Hay una lib [minitar] de ruby ​​(http://www.assembla.com/code/breakout-control/git/nodes/lib/minitar.rb?rev=6b517b950d8b422bde46ff9697b06dfbf06a66c6), lea ejemplos del código. – Vitalie

+0

no del todo cierto, mira mi respuesta – fringd

Cuestiones relacionadas