Rails Binary Stream支持
我即将开始一个需要支持大型二进制文件的项目。我想在Webapp上使用Ruby on Rails,但是我对BLOB的支持感到担忧。根据我在其他语言,框架和数据库中的经验,BLOB通常被忽略,因此功能差,困难和/或者错误。
RoR是否充分分配BLOB?一旦我们已经致力于Rails,是否会有任何陷阱?
顺便说一句:我想使用PostgreSQL和/或者MySQL作为后端数据库。显然,底层数据库对BLOB的支持很重要。目前,我想避免关注数据库的BLOB功能。我对Rails本身的反应更感兴趣。理想情况下,Rails应该向我隐藏数据库的详细信息,因此我应该能够从一个切换到另一个。如果不是这种情况(即:将Rails与特定的数据库一起使用会出现问题),请务必提及。
更新:另外,我在这里不仅在谈论ActiveRecord。我需要在HTTP端处理二进制文件(有效地上传文件)。这意味着可以通过Rails访问适当的HTTP标头和流。我已经更新了问题标题和描述以反映这一点。
解决方案
回答
我认为我们最好的选择是attachment_fu插件:
http://github.com/technoweenie/attachment_fu/tree/master
更新:在此处找到更多信息http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/a81beffb93708bb3
回答
我们可以在ActiveRecord迁移中使用:binary
类型,也可以限制最大大小:
class BlobTest < ActiveRecord::Migration def self.up create_table :files do |t| t.column :file_data, :binary, :limit => 1.megabyte end end end
ActiveRecord将BLOB(或者CLOB)内容公开为Ruby String。
回答
+1(对于attach_fu)
我在其中一个应用程序中使用了attachment_fu,并且必须将文件存储在数据库中(出于恼人的原因,这超出了这个convo的范围)。
处理w / BLOB的(一个?)棘手的事情是,我们需要一个单独的代码路径来将数据发送给用户-我们不能像在文件系统中那样简单地内联路径纯简文件。
例如如果我们要存储头像信息,则不能简单地执行以下操作:
<%= image_tag @youruser.avatar.path %>
我们必须编写一些包装器逻辑并使用send_data,例如(下面仅是一个带有附件的示例,实际上,我们需要对此进行干燥)
send_data(@youruser.avatar.current_data, :type => @youruser.avatar.content_type, :filename => @youruser.avatar.filename, :disposition => 'inline' )
不幸的是,据我所知,attachment_fu(我没有最新版本)不能为我们提供巧妙的包装-我们必须自己编写。
P.S.
看到问题编辑后,Attachment_fu处理了我们提到的所有烦人的事情-关于需要知道文件路径和所有废话的内容-除了存储在数据库中的一个小问题。试试看;这是Rails应用程序的标准。如果我们坚持要重新发明轮子,那么attachment_fu的源代码也应该记录大多数陷阱!
回答
看看插件x_send_file。
" XSendFile插件提供了一个简单的界面,用于通过X-Sendfile HTTP标头发送文件。这使Web服务器可以直接从磁盘提供文件,而不是通过Rails流程对其进行流传输。这更快并且节省了大量内存如果我们使用的是Mongrel,则并非每个Web服务器都支持此标头。
我不确定它是否可用于Blob,它可能仅适用于文件系统上的文件。但是我们可能需要一些不会阻塞Web服务器的流大量数据的东西。
回答
对于流媒体,我们可以(至少在内存方面)高效的方式完成所有操作。在上传方面,表格中的文件参数被抽象为我们可以读取的IO对象。在下载端,查看带有Proc参数的render:text =>
形式:
render :content_type => 'application/octet-stream', :text => Proc.new { |response, output| # do something that reads data and writes it to output }
但是,如果东西在磁盘上的文件中,则上述解决方案肯定会更好地工作。