Skip to content

Instantly share code, notes, and snippets.

@ryochin
Created May 21, 2020 01:39
Show Gist options
  • Save ryochin/8197925539b5f73f1e9538e9b59cc491 to your computer and use it in GitHub Desktop.
Save ryochin/8197925539b5f73f1e9538e9b59cc491 to your computer and use it in GitHub Desktop.
[Ruby] roughly split & save the downloaded file.
#!/usr/bin/env ruby
# frozen_string_literal: true
# roughly split & save the downloaded file.
class Main
require 'uri'
require 'net/http'
require 'fileutils'
require 'thwait'
FILE_URI = 'http://archive.apache.org/dist/httpd/httpd-2.4.43.tar.bz2'
def initialize
@dir = './chunked_data'
FileUtils.rm_rf @dir
FileUtils.mkdir_p @dir
@size_limit = 2 * 1024 ** 2
@uri = URI.parse(FILE_URI)
end
def run
http = Net::HTTP.new(@uri.host)
http.read_timeout = 5
pos = 1
chunk = ''
threads = []
http.request_get(@uri.path) do |response|
response.read_body do |data|
chunk += data
# split & save content (async)
if chunk.size > @size_limit
threads << Thread.new(pos, chunk) do |p, c|
save_content p, c
end
chunk = ''
pos += 1
end
end
end
# save the remnant (sync)
if chunk.size.positive?
save_content pos, chunk
else
pos -= 1
end
# wait all threads done
ThreadsWait.new(*threads)
puts '=> total %d files saved' % pos
end
private
def save_content(pos, chunk)
sleep 2
File.open file(pos), 'wb' do |f|
f.write chunk
end
puts 'file %d saved (%d)' % [pos, chunk.size]
end
def file(pos)
File.join(@dir, '%02d.bin' % pos)
end
end
Main.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment