2009-03-19 12 views
8

Vorrei poter visualizzare l'avanzamento di un'operazione di copia dei file durante la copia dei file utilizzando Ruby (attualmente utilizzando FileUtils.cp) Ho provato a impostare l'opzione verbose su true ma solo sembra mostrarmi il comando di copia emesso.Ruby show progressi durante la copia dei file

Al momento sto eseguendo questo script dalla riga di comando, quindi idealmente mi piacerebbe essere in grado di presentare qualcosa come SCP quando copia i file, ma non sono troppo preoccupato per la presentazione finché puoi vedere i progressi.

risposta

14

Come non ho abbastanza rep per modificare le risposte, ma qui è la mia versione basata sulla risposta pisswillis, ho trovato un progress bar gem che sto anche usando nel mio esempio. Ho testato 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 
+2

ben fatto. E grazie per avermi fatto conoscere la gemma progressbar. – pisswillis

+0

gemma utile +1 per quello :) – JstRoRR

7

Rotolo il proprio utilizzando IO.syswrite, IO.sysread.

primo luogo, decidere la lunghezza della barra di avanzamento (in caratteri) .. allora 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 metodo per incrementare la barra di avanzamento per uno char. Quanto sopra non è testato e probabilmente renderà i puristi di rubino malati. In particolare una EOFException potrebbe rovinare il ciclo. Inoltre avrai bisogno di un modo per assicurarti che tutti i byte siano scritti se no_of_bytes non è un numero intero.

+0

Un ottimo punto di partenza, ma non potendo modificarlo ho dovuto aggiungere la mia risposta con il mio codice di lavoro. – DEfusion

5

Oppure si potrebbe incidere in modo da utilizzare SCP, se questa è la barra di avanzamento che ti piace:

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

Dovrete assicurarsi che i nomi di origine e dest sono adeguatamente sfuggiti 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.

+0

Che bella idea, non ci ho pensato. – DEfusion

0

In Windows non dimenticare di aggiungere il 'b' per i file binari, in modo da 'w' e' r 'dovrebbe essere' wb 'e' rb 'per i file binari.

in_file  = File.new(in_name, "rb") 
out_file = File.new(out_name, "wb") 
Problemi correlati