Pergunta

Eu gostaria de ser capaz de mostrar o progresso de uma operação de cópia de arquivo ao copiar arquivos usando Ruby (usando atualmente FileUtils.cp) Eu tentei definindo a opção verbose para true mas que apenas parece-me mostrar a cópia comando emitido.

Estou executando esse script de linha de comando no momento, então Idealmente, eu gostaria de ser capaz de apresentar algo como SCP faz arquivos quando se copia, mas eu não estou com muita pressa sobre a apresentação, enquanto eu puder ver o progresso.

Foi útil?

Solução

Como eu não tenho rep suficiente para editar respostas ainda aqui é a minha versão com base na resposta pisswillis, eu encontrei um barra de progresso gem que eu também estou usando no meu exemplo. Eu testei isso e tem funcionado bem até agora, mas poderia fazer com alguma limpeza:

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

Outras dicas

Roll seu próprio utilizando IO.syswrite, IO.sysread.

Em primeiro lugar, a duração da barra de progresso (em caracteres) decidir .. então este código pseudo deve fazê-lo (não testado):

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

onde update_progress_bar () é o seu método para incrementar a barra de progresso por um caractere. O acima não é testado e provavelmente fará com que os puristas rubi doente. Em particular um EOFException poder atrapalhar o loop. Além disso, você vai precisar de alguma maneira de ter certeza que todos os bytes são escritos se no_of_bytes não é um inteiro.

Ou você poderia apenas cortá-lo de usar scp, se essa é a barra de progresso que você gosta:

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

Você tem que ter certeza a origem e os nomes dest estão devidamente escapou para uma chamada de sistema. O localhost: tag marcas scp copiar os arquivos como faz entre computadores, então ele irá mostrar uma barra de progresso.

No Windows não se esqueça de adicionar o 'b' para arquivos binários, de modo 'w' e 'r' deve ser 'wb' e 'rb' para arquivos binários.

in_file     = File.new(in_name, "rb")
out_file    = File.new(out_name, "wb")
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top