Being an FTP Client
Problem
You want to automatically connect to an FTP server, and upload or download files.
Solution
Use the Net::FTP class. It provides a filesystem-like interface to an FTP server. In this example, I log anonymously into a popular FTP site, browse one of its directories, and download two of its files:
require et/ftp ftp = Net::FTP.open(ftp.ibiblio.org) do |ftp| ftp.login ftp.chdir(pub/linux/) ftp.list(*Linux*) { |file| puts file } puts puts Saving a text file to disk while processing it. ftp.gettextfile(How-do-I-get-Linux) { |line| puts "! #{line}" } puts "Saved #{File.size How-do-I-get-Linux} bytes." puts puts Saving a binary file to disk. ftp.getbinaryfile(INDEX.whole.gz) puts "Saved #{File.size INDEX.whole.gz} bytes." end # -rw-r--r-- 1 (?) users 16979001 Jan 1 11:31 00-find.Linux.gz # -rw-rw-r-- 1 (?) admin 73 Mar 9 2001 How-do-I-get-Linux # Saving a text file to disk while processing it. # ! # ! Browse to http://metalab.unc.edu/linux/HOWTO/Installation-HOWTO.html # ! # Saved 73 bytes. # Saving a binary file to disk. # Saved 213507 bytes.
Discussion
Once the preferred way of storing and serving files through the Internet, FTP is being largely superceded by SCP for copying files, the web for distributing files, and Bit-Torrent for distributing very large files. There are still many anonymous FTP servers, though, and many web hosting companies still expect you to upload your web pages through FTP.
The login method logs in to the server. Calling it without arguments logs you in anonymously, which traditionally limits you to download privileges. Calling it with a username and password logs you in to the server:
ftp.login(leonardr, mypass)
The methods chdir and list let you navigate the FTP servers directory structure. They work more or less like the Unix cd and ls commands (in fact, list is aliased to ls and dir).
There are also two "get" methods and two "put" methods. The "get" methods are getbinaryfile and gettextfile. They retrieve the named file from the FTP server and write it to disk. The gettextfile method converts between platform-specific newline formats as it downloads. This way you can download a text file from a Unix server to your Windows machine, and have the Unix newlines automatically converted into Windows newlines. On the other hand, if you use gettextfile on a binary file, youll probably corrupt the file as you download it.
You can specify a local name for the file and a block to process the data as it comes in. A block passed into gettextfile will be called for each line of a downloaded file; a block passed into getbinaryfile will be passed for each downloaded chunk.
A file you download with one of the "get" methods will be written to disk even if you pass in a block to process it. If you want to process a file without writing it to disk, just define some methods like these:
class Net::FTP def processtextfile(remotefile) retrlines(RETR + remotefile) { |line| yield line } end def processbinaryfile(remotefile, blocksize=DEFAULT_BLOCKSIZE) retrbinary(RETR + remotefile, blocksize) { |data| yield data } end end
The two "put" methods are (you guessed it) puttextfile and putbinaryfile. They are the exact opposites of their get counterparts: they take the path to a local file, and write it to a file on the FTP server. They, too, can take a code block that processes each line or chunk of the file as its read. This example automatically uploads the index.html file to my ISPs hosted web space.
require et/ ftp Net::FTP.open(myisp.example.com) do |ftp| ftp.login(leonardr, mypass) ftp.chdir(public_html) ftp.puttextfile(index.html) end
In general, you can use the "put" methods if you e logged in as an anonymous user. Some FTP servers do have special incoming/ directories to which anonymous users can upload their submissions.
See Also
- ri Net::FTP
Категории