Ruby показывает прогресс при копировании файлов - PullRequest
8 голосов
/ 19 марта 2009

Я хотел бы иметь возможность показывать ход операции копирования файлов при копировании файлов с использованием Ruby (в настоящее время используется FileUtils.cp). Я попытался установить для параметра verbose значение true, но это только кажется покажи мне выданную команду копирования.

В настоящий момент я запускаю этот скрипт из командной строки, поэтому в идеале я хотел бы иметь возможность представлять что-то, что делает SCP, когда копирует файлы, но я не слишком беспокоюсь о презентации, пока могу увидеть прогресс.

Ответы [ 4 ]

14 голосов
/ 19 марта 2009

Поскольку у меня недостаточно репов для редактирования ответов, здесь моя версия, основанная на ответе Писвиллиса, я нашел гем индикатора прогресса , который я также использую в своем примере. Я проверил это, и до сих пор оно работало нормально, но это можно сделать с некоторой очисткой:

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
7 голосов
/ 19 марта 2009

Сверните свое собственное использование 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 не является целым числом.

6 голосов
/ 19 марта 2009

Или вы можете просто взломать его, чтобы использовать scp, если вам нравится индикатор выполнения:

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

Вы должны будете убедиться, что имена источника и назначения правильно экранированы для системного вызова. Тег localhost: заставляет scp копировать файлы, как это происходит между компьютерами, поэтому он будет отображать индикатор выполнения.

0 голосов
/ 25 июля 2014

В Windows не забудьте добавить «b» для двоичных файлов, поэтому «w» и «r» должны быть «wb» и «rb» для двоичных файлов.

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