Ruby在复制文件时显示进度

时间:2009-03-19 11:48:58

标签: ruby file file-io copy progress

我希望能够在使用Ruby复制文件时显示文件复制操作的进度(目前正在使用FileUtils.cp)我尝试将verbose选项设置为true但是这似乎只是向我展示了发出的复制命令。

我现在正在从命令行运行这个脚本,所以理想情况下,我希望能够在复制文件时呈现像SCP那样的内容,但只要我能够,我就不会对该演示文稿感到太过兴奋看到进展。

4 个答案:

答案 0 :(得分:14)

由于我没有足够的代表来编辑答案,这里是基于pisswillis答案的我的版本,我找到了progress bar gem,我也在我的例子中使用。我已经对此进行了测试,到目前为止它已经运行良好,但它可以用一些清理工作:

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

答案 1 :(得分:7)

使用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()是将进度条增加一个char的方法。 上面没有经过测试,可能会让红宝石纯粹主义者生病。特别是EOFException可能会搞乱循环。如果no_of_bytes不是整数,你还需要一些方法来确保写入所有字节。

答案 2 :(得分:6)

或者你可以破解它使用scp,如果这是你喜欢的进度条:

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

您必须确保为系统调用正确转义源名称和目的地名称。 localhost:标记使scp复制文件,因为它会显示进度条。

答案 3 :(得分:0)

在Windows下,不要忘记添加&#39; b&#39;对于二进制文件,所以&#39; w&#39;和&#39; r&#39;应该是&#39; wb&#39;和&#39; rb&#39;对于二进制文件。

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