2009-03-19 36 views
8

Tôi muốn có thể hiển thị tiến trình của thao tác sao chép tệp khi sao chép tệp bằng Ruby (hiện đang sử dụng FileUtils.cp) Tôi đã thử đặt tùy chọn verbose thành true nhưng chỉ dường như cho tôi thấy lệnh sao chép đã được phát hành.Ruby hiển thị tiến trình khi sao chép tệp

Tôi đang chạy tập lệnh này từ dòng lệnh vì vậy lý tưởng tôi muốn có thể trình bày một cái gì đó như SCP thực hiện khi sao chép tệp, nhưng tôi không quá phiền phức về bản trình bày miễn là tôi có thể thấy sự tiến bộ.

Trả lời

14

Vì tôi không có đủ đại diện để chỉnh sửa câu trả lời nhưng đây là phiên bản của tôi dựa trên câu trả lời pisswillis, tôi đã tìm thấy progress bar gem mà tôi cũng đang sử dụng trong ví dụ của mình. Tôi đã thử nghiệm này và nó đã làm việc OK cho đến nay, nhưng nó có thể làm với một số làm sạch lên:

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 
+2

được thực hiện tốt. Và cảm ơn bạn đã giới thiệu tôi với gem thanh tiến trình. – pisswillis

+0

gem hữu ích +1 cho điều đó :) – JstRoRR

7

Cuộn của riêng bạn bằng cách sử dụng IO.syswrite, IO.sysread.

tiên, quyết định chiều dài của thanh tiến trình (trong chars) .. sau đó mã giả này nên làm điều đó (không kiểm tra):

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 

nơi update_progress_bar() là phương pháp của bạn để tăng thanh tiến trình của một char. Ở trên không được thử nghiệm và có thể sẽ làm cho người thuần túy ruby ​​bị bệnh. Đặc biệt là một EOFException có thể mess lên vòng lặp. Ngoài ra, bạn sẽ cần một số cách để đảm bảo rằng tất cả các byte được viết nếu no_of_bytes không phải là một số nguyên.

+0

Điểm khởi đầu tuyệt vời, nhưng khi tôi không thể chỉnh sửa, tôi phải thêm câu trả lời của riêng mình bằng mã làm việc của mình. – DEfusion

5

Hoặc bạn chỉ có thể hack nó để sử dụng scp, nếu đó là thanh tiến trình bạn thích:

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

Bạn sẽ phải đảm bảo nguồn và đích tên được thoát đúng cho một cuộc gọi hệ thống. Thẻ localhost: làm cho scp sao chép các tệp như giữa các máy tính, vì vậy nó sẽ hiển thị thanh tiến trình.

+0

Thật là một ý tưởng tuyệt vời, không nghĩ về điều đó. – DEfusion

0

Dưới Windows đừng quên thêm 'b' cho tệp nhị phân, vì vậy 'w' và ' r 'nên là' wb 'và' rb 'cho các tệp nhị phân.

in_file  = File.new(in_name, "rb") 
out_file = File.new(out_name, "wb") 
Các vấn đề liên quan