2009-03-19 15 views
8

Me gustaría poder mostrar el progreso de una operación de copia de archivo al copiar archivos usando Ruby (actualmente usando FileUtils.cp) He intentado configurar la opción verbose en true pero solo parece mostrarme el comando de copia emitido.Ruby muestra el progreso al copiar archivos

Estoy ejecutando esta secuencia de comandos desde la línea de comandos en este momento, así que idealmente me gustaría poder presentar algo así como SCP cuando copia archivos, pero no estoy demasiado preocupado por la presentación, siempre y cuando puede ver el progreso

Respuesta

14

Como no tengo suficiente representante para editar las respuestas, pero esta es mi versión basada en la respuesta de pisswillis, encontré un progress bar gem que también estoy usando en mi ejemplo. He probado esto y ha funcionado bien hasta ahora, pero podría hacer con un poco de limpieza:

require 'rubygems' 
require 'progressbar' 

in_name  = "src_file.txt" 
out_name = "dest_file.txt" 

in_file  = File.new(in_name, "r") 
out_file = File.new(out_name, "w") 

in_size  = File.size(in_name) 
# Edit: float division. 
batch_bytes = (in_size/100.0).ceil 
total  = 0 
p_bar  = ProgressBar.new('Copying', 100) 

buffer  = in_file.sysread(batch_bytes) 
while total < in_size do 
out_file.syswrite(buffer) 
p_bar.inc 
total += batch_bytes 
if (in_size - total) < batch_bytes 
    batch_bytes = (in_size - total) 
end 
buffer = in_file.sysread(batch_bytes) 
end 
p_bar.finish 
+2

muy bien hecho. Y gracias por presentarme la joya de la barra de progreso. – pisswillis

+0

gema útil +1 para eso :) – JstRoRR

7

Hazlo tu mismo usando IO.syswrite, IO.sysread.

primer lugar, decidir la longitud de la barra de progreso (en caracteres) .. entonces este pseudo código debería hacerlo (no probado):

infile = File.new("source", "r") 
outfile = File.new("target", "w") 

no_of_bytes = infile.length/PROGRESS_BAR_LENGTH 

buffer = infile.sysread(no_of_bytes) 
while buffer do 
outfile = syswrite(buffer) 
update_progress_bar() 
buffer = infile.sysread(no_of_bytes) 
end 

donde update_progress_bar() es su método para incrementar la barra de progreso por uno carbonizarse. Lo anterior no está probado y probablemente hará que los puristas de rubí se enfermen. En particular, una EOFException podría arruinar el ciclo. También necesitará alguna forma de asegurarse de escribir todos los bytes si no_of_bytes no es un número entero.

+0

Un gran punto de partida, pero como no pude editarlo, tuve que agregar mi propia respuesta con mi código de trabajo. – DEfusion

5

O usted podría entrar ilegalmente en él para usar scp, si esa es la barra de progreso le gusta:

def copy(source, dest) 
    `scp #{source} localhost:#{dest}` 
end 

Vas a tener que asegurarse de que los nombres de la fuente y dest son escapados correctamente para una llamada al sistema. La etiqueta localhost: hace que scp copie los archivos como lo hace entre las computadoras, por lo que mostrará una barra de progreso.

+0

Qué gran idea, no pensé en eso. – DEfusion

0

En Windows no se olvide de añadir el 'b' para los archivos binarios, por lo que 'w' y ' r 'debe ser' wb 'y' rb 'para archivos binarios.

in_file  = File.new(in_name, "rb") 
out_file = File.new(out_name, "wb") 
Cuestiones relacionadas