Ruby 将字符串转换为文件以上传到 FTP
Ruby converting String to File for uploading to FTP
目前我们有一种方法可以 returns 一个带有格式化 CSV 文件的字符串。
string = EXPORT.tickets
我们需要像这样将此 csv 文件上传到 ftp 服务器
ftp = Net::FTP.new(server, username, password)
ftp.putbinaryfile(string)
然而,string
变量显然是一个字符串,而不是 putbinaryfile 方法所期望的二进制文件。我看到有两种方法可以做到这一点,
- 首先使用
File
将 string
变量转换为文件
- 将字符串直接转换为类似
StringIO
的文件
这些看起来是可行的选择吗?如果是这样,我将如何处理,在此先感谢!
编辑:
由于 putbinaryfile 方法正在查找文件路径而不是实际文件,看来我最好的办法是从 string
变量创建一个文件。谁能举例说明如何实现这一点?
类似这样的内容应该涵盖大部分基础:
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')
本地临时文件仍然有一个唯一的名称,但您不必关心这个。
在与另一位开发人员交谈后,他给了我这个解决方案,我发现这个解决方案更适合我的情况,因为该文件当时还不存在。它跳过将字符串写入临时文件并使用 StringIO 直接上传它。他的解决方案:
Net::FTP#putbinaryfile 方法将本地文件系统上文件的 name 复制到远程文件系统。现在,如果你的数据是一个字符串(并且不是从文件系统上的文件中读取的)那么你可能想要使用 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
以上避免了将不在磁盘上的数据写入磁盘,这样您就可以将其上传到某个地方。但是,如果数据已经在磁盘上的文件中,您也可以修改代码以引用其文件名。
目前我们有一种方法可以 returns 一个带有格式化 CSV 文件的字符串。
string = EXPORT.tickets
我们需要像这样将此 csv 文件上传到 ftp 服务器
ftp = Net::FTP.new(server, username, password)
ftp.putbinaryfile(string)
然而,string
变量显然是一个字符串,而不是 putbinaryfile 方法所期望的二进制文件。我看到有两种方法可以做到这一点,
- 首先使用
File
将 - 将字符串直接转换为类似
StringIO
的文件
string
变量转换为文件
这些看起来是可行的选择吗?如果是这样,我将如何处理,在此先感谢!
编辑:
由于 putbinaryfile 方法正在查找文件路径而不是实际文件,看来我最好的办法是从 string
变量创建一个文件。谁能举例说明如何实现这一点?
类似这样的内容应该涵盖大部分基础:
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')
本地临时文件仍然有一个唯一的名称,但您不必关心这个。
在与另一位开发人员交谈后,他给了我这个解决方案,我发现这个解决方案更适合我的情况,因为该文件当时还不存在。它跳过将字符串写入临时文件并使用 StringIO 直接上传它。他的解决方案:
Net::FTP#putbinaryfile 方法将本地文件系统上文件的 name 复制到远程文件系统。现在,如果你的数据是一个字符串(并且不是从文件系统上的文件中读取的)那么你可能想要使用 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
以上避免了将不在磁盘上的数据写入磁盘,这样您就可以将其上传到某个地方。但是,如果数据已经在磁盘上的文件中,您也可以修改代码以引用其文件名。