Ruby muestra el progreso al copiar archivos
Pregunta
Me gustaría poder mostrar el progreso de una operación de copia de archivos al copiar archivos usando Ruby (actualmente usando FileUtils.cp) He intentado configurar la opción verbose
en true
pero eso parece muéstrame el comando de copia emitido.
Estoy ejecutando este script desde la línea de comandos en este momento, así que idealmente me gustaría poder presentar algo como SCP cuando copia archivos, pero no estoy demasiado preocupado por la presentación siempre que pueda ver el progreso.
Solución
Como todavía no tengo suficiente representante para editar las respuestas, aquí está mi versión basada en la respuesta pisswillis, encontré un gema de la barra de progreso que también estoy usando en mi ejemplo. He probado esto y ha funcionado bien hasta ahora, pero podría funcionar 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
Otros consejos
Ruede el suyo usando IO.syswrite, IO.sysread.
Primero, decida la longitud de la barra de progreso (en caracteres) ... luego este pseudocó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 en un carácter. Lo anterior no se ha probado y probablemente enfermará a los puristas del rubí. En particular, una EOFException podría estropear el ciclo. También necesitará alguna forma de asegurarse de que todos los bytes se escriban si no_of_bytes no es un entero.
O simplemente podría hackearlo para usar scp, si esa es la barra de progreso que le gusta:
def copy(source, dest)
`scp #{source} localhost:#{dest}`
end
Tendrá que asegurarse de que los nombres de origen y destino se escapen correctamente para una llamada al sistema. La etiqueta localhost:
hace que scp copie los archivos como lo hace entre computadoras, por lo que mostrará una barra de progreso.
En Windows no olvide agregar la 'b' para archivos binarios, por lo que 'w' y 'r' deberían ser 'wb' y 'rb' para archivos binarios.
in_file = File.new(in_name, "rb")
out_file = File.new(out_name, "wb")