How to Ftp in Ruby Without First Saving the Text File

How to FTP in Ruby without first saving the text file

StringIO.new provides an object that acts like an opened file. It's easy to create a method like puttextfile, by using StringIO object instead of file.

require 'net/ftp'
require 'stringio'

class Net::FTP
def puttextcontent(content, remotefile, &block)
f = StringIO.new(content)
begin
storlines("STOR " + remotefile, f, &block)
ensure
f.close
end
end
end

file_content = <<filecontent
<html>
<head><title>Hello!</title></head>
<body>Hello.</body>
</html>
filecontent

ftp = Net::FTP.new(domain)
ftp.passive = true
ftp.login(username, password)
ftp.chdir(path_on_server)
ftp.puttextcontent(file_content, path_to_web_file)
ftp.close

Retrieving text file using Net::FTP without login

Login using the username "anonymous" and either "guest" or your email address as the password:

ftp = Net::FTP.new ('tgftp.nws.noaa.gov')
ftp.passive = true
ftp.login 'anonymous', 'guest'
ftp.chdir ('/data/observations/metar/stations')
...

You'll find more info about anonymous FTP here.

Download multiple FTP files like d*.txt in ruby

The simplest way would be to loop through the list of files in fileList.

Here is an example (untested):

ftp = Net::FTP::new("ftp_server_site")
ftp.login("user", "pwd")
ftp.chdir("/RemoteDir")
fileList = ftp.list('D*.txt')
fileList.each do |file|
ftp.gettextfile(file)
end
ftp.close

Hope this helps.

Ruby converting String to File for uploading to FTP

After talking to another developer, he gave me this solution which I found to be a better for my situation, since the file did not exist already. It skips writing the string to a Tempfile and uses StringIO to upload it directly. His solution:

The Net::FTP#putbinaryfile method takes the name of a file on the local filesystem to copy to the remote filesystem. Now, if your data is in a string (and wasn't read from a file on the filesystem) then you may want to use Net::FTP#storbinary instead:

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

The above avoids writing data that's not on disk to disk, just so you can upload it somewhere. However, if the data is already in a file on disk, you might as well just fix your code to reference its filename instead.

Rails upload file to ftp server

After much research and head banging, I ended up reading the source code for putbinaryfile method to figure out a workaround for the limitation of putbinaryfile. Here's the working code, replace this line

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

with

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

And in case you are wondering, STOR is a raw FTP command, yeah it came to that. I'm rather surprised this scenario isn't more easily handled by Ruby standard libraries, it certainly wasn't obvious what needed to be done.

And if your app is on Heroku, add this line

ftp.passive = true

Heroku's firewall setup does not allow for FTP active mode, also make sure that your FTP server supports passive mode.



Related Topics



Leave a reply



Submit