Ruby 3.0环境无法通过URL下载图片/视频文件报错如何解决
报错原因
- Ruby 3.0 版本不再默认加载
open-uri网络请求标准库,直接调用open()传入URL时,Ruby会把传入的网络地址识别为本地文件路径,去本地磁盘查找对应路径的文件,自然抛出Errno::ENOENT找不到文件的错误。 - 代码里的保存路径
/Users/{username}/Documents/test.jpg中{username}是占位符,未替换为系统实际用户名,即便网络请求正常,也会因为目标目录不存在触发写入错误。
修复方案
- 代码开头手动引入Ruby自带的
open-uri库,不需要额外安装第三方gem。 - 替换硬编码的文件路径占位符,推荐用Ruby内置方法动态获取当前用户目录,避免手动修改用户名的麻烦。
- 优化文件读写逻辑,使用流复制方式处理下载,支持大体积mp4视频下载,不会一次性把整个文件加载进内存造成内存占用过高。
可直接运行的修复后代码
# 必须手动引入open-uri库,Ruby3.0无默认加载 require 'open-uri' target_url = "https://images.pexels.com/photos/60597/dahlia-red-blossom-bloom-60597.jpeg?cs=srgb&dl=pexels-pixabay-60597.jpg&fm=jpg" # 自动拼接当前用户的文档目录路径,兼容不同系统用户 save_path = File.join(Dir.home, 'Documents', 'test.jpg') # 流式下载写入,支持图片、mp4等任意大小的文件 URI.open(target_url, 'rb') do |remote_resource| File.open(save_path, 'wb') do |local_file| IO.copy_stream(remote_resource, local_file) end end
补充说明
- 如果访问HTTPS链接时遇到SSL证书校验错误,可在
URI.open参数中添加SSL校验跳过配置(仅用于确认可信的下载源,避免下载恶意文件),写法如下:URI.open(target_url, 'rb', ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE) - 代码中使用的
IO.copy_stream是Ruby内置的高效流复制方法,会自动按固定块大小读写数据,即便是下载数GB大小的长视频,也不会出现内存占满的问题。
内容的提问来源于stack exchange,提问作者sagar verma
相关产品推荐
相关产品推荐

