Ruby показывает прогресс при копировании файлов
Вопрос
Я хотел бы иметь возможность показывать ход операции копирования файлов при копировании файлов с помощью Ruby (в настоящее время с использованием FileUtils.cp). Я пробовал установить verbose
возможность true
но это, кажется, просто показывает мне выданную команду копирования.
В данный момент я запускаю этот скрипт из командной строки, поэтому в идеале мне хотелось бы иметь возможность представить что-то вроде SCP, когда он копирует файлы, но меня не слишком беспокоит презентация, пока я вижу прогресс. .
Решение
Поскольку у меня недостаточно представителей для редактирования ответов, вот моя версия, основанная на ответе Писвиллиса, я нашел драгоценный камень индикатора прогресса который я также использую в своем примере.Я протестировал это, и до сих пор все работало нормально, но можно было бы внести некоторую очистку:
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
Другие советы
Создайте свой собственный, используя IO.syswrite, IO.sysread.
Сначала определите длину индикатора выполнения (в символах).тогда этот псевдокод должен это сделать (НЕ ПРОВЕРЕНО):
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
где update_progress_bar() — ваш метод увеличения индикатора выполнения на один символ.Вышеупомянутое не проверено и, вероятно, нанесет вред пуристам.В частности, исключение EOFException может испортить цикл.Также вам понадобится какой-то способ убедиться, что все байты записаны, если no_of_bytes не является целым числом.
Или вы можете просто взломать его, чтобы использовать scp, если вам нравится такой индикатор выполнения:
def copy(source, dest)
`scp #{source} localhost:#{dest}`
end
Вам необходимо убедиться, что имена источника и назначения правильно экранированы для системного вызова.А localhost:
Тег scp заставляет scp копировать файлы между компьютерами так же, как и между компьютерами, поэтому отображается индикатор выполнения.
В Windows не забудьте добавить букву «b» для двоичных файлов, поэтому «w» и «r» должны быть «wb» и «rb» для двоичных файлов.
in_file = File.new(in_name, "rb")
out_file = File.new(out_name, "wb")