Skip to content

Instantly share code, notes, and snippets.

@wojtha
Last active February 3, 2023 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wojtha/a06b575e77e26083a735f19dd17b03e2 to your computer and use it in GitHub Desktop.
Save wojtha/a06b575e77e26083a735f19dd17b03e2 to your computer and use it in GitHub Desktop.
Download binary file with 'open-uri' and 'IO.copy_stream'
require 'open-uri'
# Net::HTTP.get(uri) does't work for binary files. File gets corrupted.
#
# File is opended in binary write mode "wb". The "open" method is provided
# by open-uri and is considered unsafe for user input! The "rb" stands for
# binary read mode.
#
# IO.copy_stream does not load the whole file in memory.
#
# See http://stackoverflow.com/a/33746205
# https://staff.aist.go.jp/tanaka-akira/pub/copy_stream-euruko2008.pdf
#
def download(uri, file, mkdir: true)
FileUtils.mkdir_p(File.dirname(file)) if mkdir
File.open(local_path, 'wb') do |file|
IO.copy_stream(open(URI(uri), 'rb'), file)
end
end
@tanema
Copy link

tanema commented Aug 5, 2020

To avoid calling Kernel#open you can re-write this to use a direct call to the open-uri API using URI#open.

def download(uri, file, mkdir: true)
  FileUtils.mkdir_p(File.dirname(file)) if mkdir
  File.open(local_path, 'wb') do |file|
    IO.copy_stream(URI.open(uri, 'rb'), file)
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment