On Apr 3, 8:26 pm, "Jeff" <cohen.j...@gmail.com> wrote:
> I'm trying to use the Net::FTP class to send a text file to my FTP
> server, but I don't have an actual text file to send. Instead I want
> to send it a multi-line string as my "file". (I'm using Builder to
> generate an XML file and I don't want to have to physically save it to
> a file before sending it.)
>
> The Net::FTP class has a method called puttextfile that seems to be
> defined like this:
>
> def puttextfile(localfile, remotefile = File.basename(localfile),
> &block)
>
> but I don't have a local filename to provide. Is there anything I can
> use that would substitute for one?
I ended up subclassing and providing the functionality myself.
In case it helps anyone, here's what I came up with: two methods,
get_text_lines and send_text_lines. See below for complete source
(it's not too long). Suggestions for making the code more elegant are
definitely welcome.
Jeff
require 'net/ftp'
class JeffFTP < Net::FTP
# Sends a collection of lines to be saved in a file on the server
# lines can be an array, or anything responding to #each
def send_text_lines(lines, remotefile, &block) # :yield: line
storlines_from_array("STOR " + remotefile, lines, &block)
end
# Gets a file from the server as a collection of text lines.
# If you don't provide a block, it will return an array of lines.
# If you provide a block, each line will be passed to the block,
# and the return value will be an empty array.
# Large files should use the block form.
def get_text_lines(remotefile, &block) # :yield: line
lines = []
retrlines("RETR " + remotefile) do |line|
if block
yield(line)
else
lines << line
end
end
lines
end
private
def storlines_from_array(cmd, lines, &block) # :yield: line
synchronize do
voidcmd("TYPE A")
conn = transfercmd(cmd)
lines.each do |line|
conn.write(line)
yield(line) if block
end
conn.close
voidresp
end
end
end