如何从 URL 下载文件并将其保存在 Rails 中?

Posted

技术标签:

【中文标题】如何从 URL 下载文件并将其保存在 Rails 中?【英文标题】:How can I download a file from a URL and save it in Rails? 【发布时间】:2011-01-31 17:40:56 【问题描述】:

我有一个我想在本地保存的图像的 URL,以便我可以使用 Paperclip 为我的应用程序生成缩略图。下载和保存图像的最佳方式是什么? (我研究了 ruby​​ 文件处理,但没有遇到任何问题。)

【问题讨论】:

【参考方案1】:

以上所有示例都很棒。 就我而言,我只是想从 URL 中的图像创建一个下载链接。

如果你想让它可下载(到你的下载文件夹),你可以在你的控制器中使用以下代码:

require 'open-uri'
file_type = url.to_s.split(".")[-1]

send_data open(url).read, filename: "some_name.#file_type", type: "image/#file_type", disposition: "attachment"

【讨论】:

【参考方案2】:

这可能是最简单的方法:

IO.copy_stream(URI.open("https://i.pinimg.com/originals/24/17/d6/2417d6b3f3dc236b0b5b80fb00b3a791.png"), 'destination.png')

【讨论】:

【参考方案3】:

我认为这是最清晰的方法:

require 'open-uri'

File.write 'image.png', open('http://example.com/image.png').read

【讨论】:

sage 我是 Rails 新手,我可以在模型或控制器或视图中添加此代码 视情况而定,但通常您会在模型或控制器方法中执行类似的操作。在 Rails 上下文中,您可能最好使用 ActiveStorage 等框架工具,而不是直接写入磁盘。【参考方案4】:

更短的版本:

require 'open-uri'
download = open('http://example.com/image.png')
IO.copy_stream(download, '~/image.png')

要保持相同的文件名:

IO.copy_stream(download, "~/#download.base_uri.to_s.split('/')[-1]")

【讨论】:

而且效率更高,因为输出不作为字符串存储在内存中。 +1 虽然显示两个答案实际上很有用,所以像我这样的人可以看到两者,考虑差异,然后出于正确的原因有意识地选择这个答案:) 我在使用 open 时收到来自 Rubocop 的安全警告。我用URI.parse(url).open 代替了它。在此处阅读有关该警察的更多信息:rubydoc.info/gems/rubocop/RuboCop/Cop/Security/Open【参考方案5】:

如果您使用的是 PaperClip,现在会自动处理从 URL 下载。

假设你有类似的东西:

class MyModel < ActiveRecord::Base
  has_attached_file :image, ...
end

在您的模型上,只需将图像指定为 URL,如下所示(故意写成):

@my_model = MyModel.new
image_url = params[:image_url]
@my_model.image = URI.parse(image_url)

您可能希望将其放入模型中的方法中。这也适用于 Heroku 的临时文件系统。

Paperclip 会从那里拿走它。

来源:paperclip documentation

【讨论】:

对于未来的搜索者,Paperclip 默认不再允许这样做:medium.com/in-the-weeds/…【参考方案6】:

试试这个:

require 'open-uri'
open('image.png', 'wb') do |file|
  file << open('http://example.com/image.png').read
end

【讨论】:

这行得通。谢谢。我在一张图片上试过这个。图像未正确写入文件。好像它已经损坏或什么的。你也能指导我在 Rails 应用程序中做同样的事情吗?我可以在 Rails 应用程序中使用它吗? 是的,您可以在 Rails 应用程序中使用它。文件未正确写入可能是因为我忘记以写入二进制模式打开目标。我现在将对其进行编辑。 这会读取内存中的整个文件。最好的方法是IO.copy_stream(open('http://example.com/image.png'), 'destination.png') rails 5, 2016,我不用require 'open-uri',直接用下面的代码 这个答案对我不起作用。正确答案在这里:***.com/a/29743394/1536309【参考方案7】:

查看标准库中的Net::HTTP。该文档提供了几个有关如何使用 HTTP 下载文档的示例。

【讨论】:

这个答案需要更多的可见性,因为Kernel#open 不仅可以访问文件,还可以通过前缀管道符号(例如open("| ls"))进行进程调用。因此,在Kernel#open的参数中使用变量输入可能会导致严重的安全风险。

以上是关于如何从 URL 下载文件并将其保存在 Rails 中?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Flutter 中的 URL 下载文件并将其保存在 iOS 共享文件夹中?

从 url 下载文件并将其上传到 AWS S3 而不保存 - node.js

如何从网络下载图像并将其保存在本地目录中?

如何从服务器下载文件并将其保存在 Android SD 卡中的特定文件夹中?

如何从 URL 下载图像并将其动态存储在我的应用程序的可绘制文件夹中?

从 URL 下载文件并将其放在 iPhone 的 Resource 文件夹中