![]() |
Net::FTP puttextfile question
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 tried to use a StringIO object, hoping to use that as my "localfile": s = StringIO.new(xml_data) but when I try to send it like this: Net::FTP.open("domain.com", "username", "secret") do |ftp| ftp.puttextfile(s, '\data\file.xml"') end I get this error: TypeError: can't convert StringIO into String from c:/ruby/lib/ruby/1.8/net/ftp.rb:571:in `open' from c:/ruby/lib/ruby/1.8/net/ftp.rb:571:in `puttextfile' from (irb):33 from c:/ruby/lib/ruby/1.8/net/ftp.rb:115:in `open' from (irb):32 Obviously it wants a filename, and I'm giving it the actual IO object instead. .NET had the concept of IO streams, and I was hoping to use something like that here, but I can't figure out how. Any ideas? Thanks! Jeff |
Re: Net::FTP puttextfile question
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 |
Re: Net::FTP puttextfile question
On 4/3/07, Jeff <cohen.jeff@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 tried to use a StringIO object, hoping to use that as my > "localfile": > > s = StringIO.new(xml_data) > > but when I try to send it like this: > > Net::FTP.open("domain.com", "username", "secret") do |ftp| > ftp.puttextfile(s, '\data\file.xml"') > end > > I get this error: > > TypeError: can't convert StringIO into String > from c:/ruby/lib/ruby/1.8/net/ftp.rb:571:in `open' > from c:/ruby/lib/ruby/1.8/net/ftp.rb:571:in `puttextfile' > from (irb):33 > from c:/ruby/lib/ruby/1.8/net/ftp.rb:115:in `open' > from (irb):32 > > Obviously it wants a filename, and I'm giving it the actual IO object > instead. .NET had the concept of IO streams, and I was hoping to use > something like that here, but I can't figure out how. > > Any ideas? Try turning the problem around and look at using open-uri instead of Net::FTP? This extends Kernel::open so that it accepts ftp and http urls as well as file names. This makes the ftp server look like a local file. So you'd do something like this (untested): require 'open-uri' open("ftp://user:secret@domain.com/data/file.xml",'w') do | f | # write your data to the IO object f here end -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/ |
| All times are GMT. The time now is 10:32 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.