Ruby mostra i progressi durante la copia dei file
Domanda
Mi piacerebbe essere in grado di mostrare l'avanzamento di un'operazione di copia di file durante la copia di file utilizzando Ruby (attualmente utilizzando FileUtils.cp) Ho provato a impostare l'opzione verbose
su true
ma sembra proprio mostrami il comando di copia emesso.
Al momento sto eseguendo questo script dalla riga di comando, quindi idealmente mi piacerebbe essere in grado di presentare qualcosa come fa SCP quando copia i file, ma non sono troppo preoccupato per la presentazione il più a lungo possibile vedere i progressi.
Soluzione
Dato che non ho abbastanza rappresentante per modificare le risposte, ecco la mia versione basata sulla risposta pisswillis, ho trovato un progress bar gem che sto usando anche nel mio esempio. Ho provato questo e ha funzionato bene finora, ma potrebbe fare con un po 'di pulizia:
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
Altri suggerimenti
Crea il tuo personale usando IO.syswrite, IO.sysread.
Per prima cosa, decidi la lunghezza della barra di avanzamento (in caratteri) .. quindi questo pseudo codice dovrebbe farlo (NON TESTATO):
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
dove update_progress_bar () è il tuo metodo per incrementare la barra di avanzamento di un carattere. Quanto sopra non è testato e probabilmente farà ammalare i puristi del rubino. In particolare, una EOFException potrebbe confondere il ciclo. Inoltre avrai bisogno di un modo per assicurarti che tutti i byte siano scritti se no_of_bytes non è un numero intero.
O potresti semplicemente hackerarlo per usare scp, se questa è la barra di avanzamento che ti piace:
def copy(source, dest)
`scp #{source} localhost:#{dest}`
end
Dovrai assicurarti che i nomi di origine e destinazione siano correttamente salvati per una chiamata di sistema. Il tag localhost:
consente a scp di copiare i file come avviene tra i computer, quindi mostrerà una barra di avanzamento.
In Windows non dimenticare di aggiungere 'b' per i file binari, quindi 'w' e 'r' dovrebbero essere 'wb' e 'rb' per i file binari.
in_file = File.new(in_name, "rb")
out_file = File.new(out_name, "wb")