Rails上传文件到FTP服务器。

13

我使用的是Rails 2.3.5和Ruby 1.8.6,正在尝试弄清楚如何让用户通过我的Rails应用程序将文件上传到不同机器上的FTP服务器。另外,我的Rails应用程序将托管在Heroku上,Heroku不支持向本地文件系统写入文件。

index.html.erb

<% form_tag '/ftp/upload', :method => :post, :multipart => true do %>
<label for="file">File to Upload</label> <%= file_field_tag "file" %>
<%= submit_tag 'Upload' %>
<% end %>

ftp_controller.rb

require 'net/ftp'

class FtpController < ApplicationController
  def upload
    file = params[:file]
    ftp = Net::FTP.new('remote-ftp-server')
    ftp.login(user = "***", passwd = "***")
    ftp.putbinaryfile(file.read, File.basename(file.original_filename))
    ftp.quit()
  end

  def index
  end

end

目前我只是在尝试让Rails应用程序在我的Windows笔记本电脑上运行。使用上面的代码,我得到了这个错误。

Errno::ENOENT in FtpController#upload
No such file or directory -.... followed by a dump of the file contents

我正在尝试上传一个CSV文件,如果这有任何区别的话。有人知道出了什么问题吗?

2个回答

21
经过多次的研究和尝试,我最终阅读了putbinaryfile方法的源代码以找到克服其限制的解决方法。下面是可用的代码,请将此行替换为原来的代码。

ftp.putbinaryfile(file.read, File.basename(file.original_filename))

ftp.storbinary("STOR " + file.original_filename, StringIO.new(file.read), Net::FTP::DEFAULT_BLOCKSIZE)

如果你在想,STOR是一个原始的FTP命令,没错就是这样。我很惊讶Ruby标准库没有更容易处理这种情况,这当然不是显而易见的需要做些什么。

如果你的应用程序在Heroku上,添加这一行代码。

ftp.passive = true

Heroku的防火墙设置不允许FTP主动模式,还要确保您的FTP服务器支持被动模式。


ftp.putbinaryfile(StringIO.new(file.read), file.original_filename, Net::FTP::DEFAULT_BLOCKSIZE) 能有效吗? - Tim Snowhite
不行,出现了错误:“无法将StringIO转换为String”。 - Bob
嘿,Rails 3 处理这个问题更好吗? - fatfrog

1

在我看来,ftp.putbinaryfile 只需要将文件的路径和名称作为第一个参数。


这有另外2个好的选择:https://dev59.com/YG435IYBdhLWcg3wxDFp - Josh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接