Chapter 17 ■ Ftp
321
ftp.retrlines('RETR README', writeline)
ftp.quit()
if name == 'main':
main()
In the listing, the cwd() function selects a new working directory on the remote system. Then the retrlines()
function begins the transfer. Its first parameter specifies a command to run on the remote system, usually RETR,
followed by a file name. Its second parameter is a function that is called, over and over again, as each line of the text
file is retrieved; if omitted, the data are simply printed to standard output. The lines are passed with the end-of-line
character stripped, so the homemade writeline() function simply appends your system’s standard line ending to
each line as it is written out.
Try running this program; there should be a file in your current directory named README after the program is done.
Basic binary file transfers work in much the same way as text-file transfers. Listing 17-3 shows an example of this.
Listing 17-3. Downloading a Binary File
#!/usr/bin/env python3
Foundations of Python Network Programming, Third Edition
https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter17/binarydl.py
import os
from ftplib import FTP
def main():
if os.path.exists('patch8.gz'):
raise IOError('refusing to overwrite your patch8.gz file')
ftp = FTP('ftp.kernel.org')
ftp.login()
ftp.cwd('/pub/linux/kernel/v1.0')
with open('patch8.gz', 'wb') as f:
ftp.retrbinary('RETR patch8.gz', f.write)
ftp.quit()
if name == 'main':
main()
When run, this program deposits a file named patch8.gz into your current working directory. The retrbinary()
function simply passes blocks of data to the specified function. This is convenient, because a file object’s write()
function expects data, so in this case, no custom function is necessary.
Advanced Binary Downloading
The ftplib module provides a second function that can be used for binary downloading: ntransfercmd(). This
command provides a lower-level interface, but it can be useful if you want to know a little bit more about what’s
going on during the download. In particular, this more advanced command lets you keep track of the number of
bytes transferred, and you can use that information to display status updates for the user. Listing 17-4 shows a sample
program that uses ntransfercmd().