使用 Ruby 将大文件上传到 S3 失败并出现内存不足错误,如何分块读取和上传?

2023-11-24

我们通过 Ruby AWS SDK (v2) 从 Windows 计算机将各种文件上传到 S3。我们已经使用 Ruby 1.9 进行了测试。我们的代码工作正常,除非遇到大文件,抛出内存不足错误。

首先,我们使用以下代码将整个文件读入内存:

:body => IO.binread(filepath),

然后在谷歌搜索后我们发现有一些方法可以用 Ruby 分块读取文件:

:body =>  File.open(filepath, 'rb') { |io| io.read },

不过,此代码并没有解决问题,而且我们找不到特定的 S3(或相关)示例来说明如何读取文件并将其以块的形式传递到 S3。整个文件仍然加载到内存中,并且对于大文件会引发内存不足错误。

我们知道我们可以将文件分割成块并使用 AWS 分段上传上传到 S3,但首选是尽可能避免这种情况(尽管如果这是唯一的方法也可以)。

我们的代码示例如下。分块读取文件、避免内存不足错误并上传到 S3 的最佳方法是什么?

require 'aws-sdk'

filepath = 'c:\path\to\some\large\file.big'
bucket = 's3-bucket-name'
s3key = 'some/s3/key/file.big'
accesskeyid = 'ACCESSKEYID'
accesskey = 'ACCESSKEYHERE'
region = 'aws-region-here'

s3 = Aws::S3::Client.new(
  :access_key_id => accesskeyid,
  :secret_access_key => accesskey,
  :region => region
  )

resp = s3.put_object(
  :bucket => bucket,
  :key => s3key,
  :body =>  File.open(filepath, 'rb') { |io| io.read },
  )

请注意,我们没有达到 S3 5GB 限制,例如 1.5GB 的文件就会发生这种情况。


适用于 Ruby 的 v2 AWS 开发工具包,aws-sdkgem,支持直接通过网络流式传输对象,而无需将它们加载到内存中。您的示例只需要进行一点小小的修正即可做到这一点:

File.open(filepath, 'rb') do |file|
  resp = s3.put_object(
   :bucket => bucket,
   :key => s3key,
   :body => file
  )
end

这是可行的,因为它允许 SDK 调用#read每次在文件对象上传递少量字节。呼唤#read在 Ruby IO 对象(例如文件)上,如果没有第一个参数,则会将整个对象读入内存,并将其作为字符串返回。这就是导致内存不足错误的原因。

也就是说,aws-sdkgem 提供了另一个更有用的接口,用于将文件上传到 Amazon S3。这个替代接口自动:

  • 对大型对象使用多部分 API
  • 可以使用多线程并行上传部分,提高上传速度
  • 计算客户端数据的MD5以进行服务端数据完整性检查。

一个简单的例子:

# notice this uses Resource, not Client
s3 = Aws::S3::Resource.new(
  :access_key_id => accesskeyid,
  :secret_access_key => accesskey,
  :region => region
)

s3.bucket(bucket).object(s3key).upload_file(filepath)

这是aws-sdk资源接口。这里有很多有用的实用程序。 Client 类仅提供基本的 API 功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Ruby 将大文件上传到 S3 失败并出现内存不足错误,如何分块读取和上传? 的相关文章

  • Rails 4:资产未在生产中加载

    我正在尝试将我的应用程序投入生产 但图像和 CSS 资源路径不起作用 这是我目前正在做的事情 图像资源位于 app assets images image jpg 样式表位于 app assets stylesheets style css
  • Rails 控制台无法运行

    rbenv 红宝石版本 2 6 6 导轨版本 5 1 4 我正在较旧的代码库中工作 ruby 2 6 6 rails 5 4 1 这是我每天使用的代码库 我必须通过 rbenv 下载一个新的 ruby 版本作为单独的存储库 这样做在我的旧代
  • Heroku 部署错误

    在 Windows 环境中 尝试部署到 Heroku 时出现以下错误 C Ruby lib ruby gems 1 8 gems heroku 1 9 13 lib heroku commands base rb 32 in 没有这样的文件
  • 使用无服务器访问 SSM 变量

    我想用无服务器变量中的 SSM 参数 https serverless com blog serverless v1 22 0 按照文档 我运行了以下命令 aws ssm put parameter name foo value bar t
  • Rails/Nginx 中的超时——最佳实践

    我正在开发一个应该在 Nginx 服务器上运行的 Rails 应用程序 根据输入 应用程序可能需要很长时间来处理请求 或者在出现错误时挂起 因此我想防止进程永远运行 除了确保客户端收到超时信号的 Nginx 配置之外 我想我可能仍然需要确保
  • 如何从 ruby​​ 中的字符串中删除所有非数字?

    用户输入数字的形式如下 1 800 432 4567 800 432 4567 800 432 4566 800 432 4567 1 800 432 4567 800 432 4567 我希望所有这些都变成没有特殊字符的剥离版本 例如18
  • 如何在 Elastic Beanstalk 上添加 PATH

    我想将 PATH 添加到包上eb deploy 软件包安装到 var www html vendor bin 可以通过SSH手动添加 但是如何使用配置文件添加PATH 我有这样的配置文件 ebextensions ec2 config 01
  • “rmagick”gem 安装问题

    我在尝试在 centos 上安装 rmagick gem 时遇到问题 以下是我得到的输出 谁能帮我识别一下我缺少什么包裹 我已经安装了所有提到的另一个堆栈溢出线程 RMagick安装错误 https stackoverflow com qu
  • 已定义方法的 Ruby 钩子?

    我一直在谷歌上搜索这个问题 但找不到答案 这让我认为答案是否定的 但我想我会在这里问 以防有人确切知道 Ruby 是否有一个钩子来定义方法 即在模块或类上 如果没有 是否有人足够熟悉该实施的情况main对象以了解它到底如何将方法复制到Obj
  • 从 API 网关自定义授权方返回的 401 缺少“Access-Control-Allow-Origin”标头

    为了防止未登录的用户通过 AWS API Gateway 调用我的 lambda 函数 我使用自定义授权者 lambda 解决方案 如果请求被授权 200 并且我从被调用的 lambda 得到响应 一切正常并且我得到Access Contr
  • Spring JMS监听器即使在异常时也会确认

    我正在使用 JMS 向 SQS 队列发送 接收消息 但是即使在使用 client acknowledge 时出现异常 我也无法重新传递消息 如何实现这一目标 我尝试了一个简单的测试 JmsListener destination test
  • 没有要加载的文件 - ffi_c (LoadError)

    这个问题困扰了我几天 每当我使用 bring to front 方法时 require rubygems require watir browser Watir Browser new browser bring to front 我收到此
  • node.js通过aws-sdk模块重命名s3对象

    是否可以通过重命名 s3 上的对象aws sdk https www npmjs com package aws sdk 我找不到解决方法 也许有一个临时解决方案 我想我会回答 因为没有人回答过 这个应该有用 create a new s3
  • AWS S3 公共对象与私有对象?

    回到 S3 我的存储桶中有图像的 URL 我将在我的应用程序中呈现这些图像 但它们被设置为私有 当我尝试单击该链接时 它显示 访问被拒绝 当我将链接的设置更改为公共时 它会通过 但是我读到公共访问并不是最安全的事情 所以这本质上是一个由两部
  • 存根和 rspec 旧语法的问题

    我正在编写一些代码并使用 rspec 但收到警告 提示语法已过时 我不太清楚应该如何编写它 it should calculate the value correctly do mock cards Card new clubs 5 Car
  • 如何使用play框架上传多个文件?

    我在用play framework 2 1 2 使用java我正在创建视图来上传多个文件 我的代码在这里 form action routes upload up enctype gt multipart form data
  • Shoulda/RSpec 匹配器 - 条件验证

    在我的代码中 我使用 Shoulda 匹配器进行了以下验证 效果很好 it should validate presence of name 在我的模型中 我已将条件添加到验证中 validates presence of name if
  • 带有 OAuth2 的 YouTube API v3:更新和删除失败并出现“权限不足”错误

    我在尝试着update and delete视频使用YouTube API v3 https developers google com youtube v3 docs videos with OAuth2 用于身份验证 https dev
  • AWS lambda 是否保证将函数更新到新版本时不会出现停机?

    默认情况下 AWS 使用LATEST更新了最新 lambda 版本的别名 我假设执行以下步骤 Now LATEST别名点版本 5 用户部署新版本的 lambda 在部署新版本时 LATEST别名仍然指向版本 5 部署完成后 Lambda 只
  • AWS RDS MySql - 如何在设置“公开可用”后允许访问

    刚刚使用默认设置和用户 密码创建了新的 AWS RDS MySql 实例 我也将其设置为publicly available并在此过程中创建新的 VPC 目前无法从我的笔记本电脑连接到此 RDS mysql h endpoint u myu

随机推荐

  • 如何在 Java 5 中屏蔽密码?

    我正在尝试用 Java 屏蔽密码 Sun java 建议了一种屏蔽密码的方法 如下所示 屏蔽密码 它使用一种简单的方法来做到这一点 public void run stop true while stop System out print
  • 使用自定义 AuthorizeAttribute 生成返回 URL

    我有一个自定义授权属性 using System using System Web Mvc using System Web Routing AttributeUsage AttributeTargets Class AttributeTa
  • 预取示例?

    任何人都可以给出一个示例或使用示例的链接 builtin prefetch在 GCC 或一般的 asm 指令 prefetcht0 中获得显着的性能优势 特别是 我希望该示例满足以下标准 这是一个简单 小型 独立的示例 删除 builtin
  • 角度/打字稿中的顺序代码执行

    如何让我的代码按顺序运行 例如 如果我有一个从服务获取一些数据的 for 循环 我想要n 1迭代仅在之后运行nth迭代已完成 我希望循环后的代码仅在 for 循环完成所有交互后才执行 示例代码 someMethod for var i 0
  • ChartJS 显示时间数据的差距

    我有这个图表 这是用 ChartJS 构建的 但是 在下午 1 点到 5 30 之间 没有数据 我想要图表做的就是显示没有数据 而不是连接两个点 这可以做到吗 理论上 我每 5 秒就有一个新值 但这可能会减少 所以我想我需要能够设置连接间隙
  • 如何在 sqlite.net PCL 中使用 InsertOrReplace?

    我正在使用这里的 sqlite net 的 PCL 版本 https github com oysteinkrog SQLite Net PCL 这是我的简单课程 public class LogEntry PrimaryKey AutoI
  • 非阻塞 API 是如何工作的?

    我一直在读Play 框架文档并发现这句话令人困惑 请注意 您可能会因此将阻塞代码包装在 期货 这并不意味着它是非阻塞的 它只是意味着 阻塞将发生在不同的线程中 你还需要做 确保您使用的线程池有足够的线程 处理阻塞 我的印象是所有这些非阻塞库
  • Swift 语言多播委托

    我正在尝试在 Swift 中实现多播委托功能 在 Objective C 中 我们有这个优秀的实现 https github com robbiehanson XMPPFramework blob master Utilities GCDM
  • 非托管内存未显示在任务管理器中

    我写了以下测试 实际上在更广泛的上下文中使用 IntPtr x Marshal AllocHGlobal 100000000 Console Write Press any key to continue Console ReadKey t
  • 关于配置首选项和js

    我想知道是否可以使用 javascript 获取 about config 中设置的某些首选项的值 动机是当用户登陆插件前端时获取我创建的 Firefox 插件中设置的首选项的值 基本上 我试图识别登陆 FE 的用户 而不要求他们明确登录
  • 如何通过 web.config 将 http 重定向到 https,将 www 重定向到非 www? [复制]

    这个问题在这里已经有答案了 我想使用 web config 将我的 ASP NET 站点上的所有请求重定向到 https 不含 www 那是 http http www https www 都应该去 https 到目前为止 我的 web c
  • 角度 - 垫子滑动切换不可见

    problem mat slide toggle 不可见 我正在尝试从下面的网址实现这个示例https material angular io components autocomplete examples 测试组件 html
  • 如何在客户端将自定义 ValidationAttribute 呈现为“da​​ta-val-xx”属性?

    给定一个如下所示的 ViewModel public class Login Required public string Username get set Required CustomValidator public string Pa
  • Angular 2滚动到底部(聊天风格)

    我有一组单细胞组件ng for loop 我已经一切就绪 但我似乎无法找出正确的 目前我有 setTimeout gt scrollToBottom 但这并不总是有效 因为图像异步地将视口向下推 在 Angular 2 中滚动到聊天窗口底部
  • 缩放存储在 S3 中的图像

    我面临的情况是 我需要将多个网站的图像存储推送到可以无限扩展的服务 S3 CloudFiles 等 到目前为止 我们已经能够允许用户在 Python 的图像库的帮助下动态生成自定义缩略图大小sorl 缩略图在姜戈 通过将我们的图像移动到 S
  • Backbone.js:过滤集合的正确方法?

    我当前使用的方法是过滤一个集合 它返回一个数组 然后使用 collection reset array 重新填充它 但是 这会修改原始集合 因此我添加了一个名为 originalCollectionArray 的数组 它跟踪集合的初始数组状
  • 为什么将 ArrayList 的泛型转换为超类不起作用?

    有人可以向我解释一下为什么标记该行吗 this line gives a compile error why 在下面的代码示例中不起作用 import java util ArrayList public class GenericCast
  • NLTK 正则表达式标记生成器在正则表达式中不能很好地处理小数点

    我正在尝试编写一个文本规范化器 需要处理的基本情况之一是像3 14 to three point one four or three point fourteen 我目前正在使用该模式 d d with nltk regexp tokeni
  • 查找两个字符串之间的相似度度量

    在Python中如何获得一个字符串与另一个字符串相似的概率 我想要得到一个十进制值 如 0 9 意味着 90 等 最好使用标准 Python 和库 e g similar Apple Appel would have a high prob
  • 使用 Ruby 将大文件上传到 S3 失败并出现内存不足错误,如何分块读取和上传?

    我们通过 Ruby AWS SDK v2 从 Windows 计算机将各种文件上传到 S3 我们已经使用 Ruby 1 9 进行了测试 我们的代码工作正常 除非遇到大文件 抛出内存不足错误 首先 我们使用以下代码将整个文件读入内存 body