【问题标题】:Ruby converting String to File for uploading to FTPRuby 将字符串转换为文件以上传到 FTP
【发布时间】:2015-03-20 08:06:39
【问题描述】:

目前我们有一个方法可以返回带有格式化 CSV 文件的字符串。

string   = EXPORT.tickets

我们需要像这样将该 csv 文件上传到 ftp 服务器

ftp = Net::FTP.new(server, username, password)
ftp.putbinaryfile(string)

然而,string 变量显然是一个字符串,而不是 putbinaryfile 方法所期望的二进制文件。我看到了两种方法来做到这一点,

  1. 首先使用Filestring 变量转换为文件
  2. 将字符串直接转换为带有StringIO 之类的文件

这些看起来是可行的选择吗?如果是这样,我将如何处理,提前谢谢!

编辑:

由于 putbinaryfile 方法正在寻找文件路径而不是实际文件,看来我最好的办法是从 string 变量创建一个文件。谁能举例说明如何做到这一点?

【问题讨论】:

  • 这不是 100%,putbinaryfile 需要二进制文件的 PATH(可能是字符串)。我可能会先创建一个文件(参见devdocs.io/ruby/file#method-c-new)然后上传它。上传后不要忘记删除文件:)
  • 你是对的,它正在寻找 PATH。你觉得我使用 Ruby Tempfile 类怎么样? devdocs.io/ruby/tempfile
  • 听起来不错!还有一件事:我认为您可以使用 puttextfile 而不是 putbinaryfile,因为 CSV 只是文本,但请务必先对此进行测试...
  • 好的,谢谢,我编辑了我的问题。基本上我从一开始就将字符串放入实际文件中遇到了麻烦,所以如果您有任何想法,请随时发布答案:)

标签: ruby csv ftp stringio


【解决方案1】:

在与另一位开发人员交谈后,他给了我这个解决方案,我发现它更适合我的情况,因为该文件尚不存在。它跳过将字符串写入 Tempfile 并使用 StringIO 直接上传它。他的解决方案:

Net::FTP#putbinaryfile 方法将本地文件系统上的文件的名称 复制到远程文件系统。现在,如果您的数据在字符串中(并且不是从文件系统上的文件中读取的),那么您可能希望使用 Net::FTP#storbinary 代替:

require 'stringio'
require 'net/ftp'

BLOCKSIZE = 512 
data      = StringIO.new("Hello, world!\n")
hostname  = "ftp.domain.tld"
username  = "username"
password  = "password"

remote_filename = "something.txt"

Net::FTP.open(hostname, username, password) do |ftp|
  # ...other ftp commands here...
  ftp.storbinary("STOR #{remote_filename}", data, BLOCKSIZE)
  # ...any other ftp commands...
end

以上内容避免了将不在磁盘上的数据写入磁盘,以便您可以将其上传到某个地方。但是,如果数据已经在磁盘上的文件中,您最好只修复代码以引用其文件名。

【讨论】:

  • 不错!这是对 Tempfile 的改进。
【解决方案2】:

这样的东西应该涵盖大部分基础:

require 'tempfile'

temp_file = Tempfile.new('for_you')
temp_file.write(string)
temp_file.close

ftp.putbinaryfile(temp_file)

temp_file.unlink

使用 Tempfile 可以让您摆脱关于唯一文件名、线程安全性等的许多问题。垃圾收集将确保您的文件被删除,即使 putbinaryfile 引发异常或类似的危险。

上传的文件将在本地和远程服务器上获得类似for_you.23423423.423.423.4 的名称。如果您希望它在远程服务器上具有特定名称,例如“daily_log_upload”,请改为:

ftp.putbinaryfile(temp_file, 'daily_log_upload')

对于本地临时文件,它仍然有一个唯一的名称,但您不必在意。

【讨论】:

  • 我相信你的意思是ftp.putbinaryfile( temp_file.path ),对吗?
  • 两种方法我都试过了,不管怎样,它显然知道如何检查它是否也是一个文件对象
  • 感谢您的回答,我也喜欢 Tempfile 解决方案
  • 不是问题的答案..这会保留文件..临时或不写入磁盘。
猜你喜欢
  • 2011-01-06
  • 2011-10-04
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
相关资源
最近更新 更多