Posted By

neil on 04/07/08


Tagged

file ruby copy callback feedback


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

webstic


file_duplication


 / Published in: Ruby
 

  1. require 'initialized_by_hash'
  2.  
  3.  
  4. # copies a file, providing feedback on the progress of the operation.
  5. #
  6. # source: a path to the file that should be duplicated
  7. # destination: a path to the the new copy
  8. # report_rate: the number of times each second to report
  9. #
  10. # example:
  11. # fd = FileDuplication.new :source => ARGV[0], :destination => ARGV[1]
  12. # fd.begin do | bytes_done, bytes_left|
  13. # puts '%i %i' % [ bytes_done, bytes_left]
  14. # end
  15. #
  16. class FileDuplication
  17.  
  18. attr_accessor :source, :destination, :report_rate
  19.  
  20. initialized_by_hash
  21.  
  22.  
  23. private
  24.  
  25. def fill_in_blanks
  26. @report_rate = 10 unless @report_rate
  27. end
  28.  
  29.  
  30. public
  31.  
  32. # begins this file duplication operation, providing feedback to the default
  33. # block as the operation progresses.
  34. #
  35. def begin
  36. # check that both source and destination have been specified
  37. raise 'cannot copy from an unspecified source' unless @source
  38. raise 'cannot copy to unspecified destination' unless @destination
  39.  
  40. begin
  41. source = File.open @source
  42. sink = File.open @destination, 'w'
  43.  
  44. bytes_done = 0
  45. bytes_left = File.size @source
  46. when_last_reported = Time.at 0
  47. scrap = ''
  48.  
  49. # report the commencement of the operation
  50. yield bytes_done, bytes_left
  51.  
  52. # while there are still some bytes left to copy..
  53. while 0 < bytes_left do
  54.  
  55. # don't try to copy more bytes than are left to copy
  56. block_size = [ 10240, bytes_left].min
  57.  
  58. # copy the bytes in the focus block
  59. source.sysread block_size, scrap
  60. sink.syswrite scrap
  61.  
  62. bytes_done += block_size
  63. bytes_left -= block_size
  64.  
  65. # if enough time has passed that another report should be made..
  66. now = Time.now
  67. if when_last_reported + 1.0 / @report_rate <= now
  68.  
  69. # report on progress
  70. yield bytes_done, bytes_left
  71.  
  72. when_last_reported = now
  73. end
  74. end
  75.  
  76. # report the completion of the operation
  77. yield bytes_done, bytes_left
  78.  
  79. ensure
  80.  
  81. sink.close if sink
  82. source.close if source
  83. end
  84. end
  85.  
  86. end
  87.  
  88. # --------------------------------------------------------------- 80 column rule

Report this snippet  

You need to login to post a comment.