9

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

我目前正在从命令行运行这个脚本,所以理想情况下我希望能够呈现像 SCP 在复制文件时所做的那样,但只要我能看到进度,我就不会太在意演示文稿.

4

4 回答 4

14

由于我没有足够的代表来编辑答案,但这里是我基于 pisswillis 答案的版本,我发现了一个进度条 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
于 2009-03-19T14:09:50.670 回答
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() 是将进度条增加一个字符的方法。以上内容未经测试,可能会使 ruby​​ 纯粹主义者生病。特别是 EOFException 可能会打乱循环。如果 no_of_bytes 不是整数,您还需要某种方法来确保写入所有字节。

于 2009-03-19T12:34:56.653 回答
6

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

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

您必须确保源名称和目标名称已正确转义以进行系统调用。该localhost:标签使 scp 像在计算机之间一样复制文件,因此它将显示一个进度条。

于 2009-03-19T13:49:08.707 回答
0

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

in_file     = File.new(in_name, "rb")
out_file    = File.new(out_name, "wb")
于 2014-07-25T12:12:45.583 回答