基于 Anaconda3 5.0.0 JupyterLab 0.27.0 使用 ftplib 演示 IPv4 和 IPv6 上传文件和下载文件
Anaconda 相关文章请先阅读
安全的安装Anaconda3 5.0.0 Windows x86_64
http://blog.csdn.net/hu_zhenghui/article/details/78154684
基于 Anaconda3 5.0.0 JupyterLab 0.27.0 使用 ftplib 演示 IPv4 和 IPv6 上传文件和下载文件
导入 ftplib 库
import ftplib
导入 os 库
import os
导入 sys 库
import sys
FTP 服务器的 IPv4 地址
FTP_HOST_IPv4 = '192.168.1.30'
FTP 服务器的 IPv6地址
FTP_HOST_IPv6 = 'fe80::b890:8aab:5c57:5cad'
FTP 服务的 端口
FTP_PORT = 21
FTP 服务的 用户名
FTP_USER = 'FTPAnonymous'
FTP 服务的 密码
FTP_PASSWD = 'FTPAnonymous'
上传的测试路径
UPLOAD_DIR = '/FTPAnonymous/Upload/'
测试文件直接使用 Python 的解释器
UPLOAD_FILENAME = sys.executable
获取测试文件的文件名
UPLOAD_BASENAME = os.path.basename(UPLOAD_FILENAME)
创建一个 FTP 会话,用于 IPv4 方式连接 FTP 服务器
FTP_SESSION_IPv4= ftplib.FTP()
为了演示 FTP 的细节,设置显示更多的调试信息
FTP_SESSION_IPv4.set_debuglevel(2)
按照 IPv4 的地址链接 FTP 服务器,在服务器的欢迎信息中,可以看到该服务器支持 IPv6
FTP_SESSION_IPv4.connect(FTP_HOST_IPv4, FTP_PORT)
*get* '220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------\n'
*get* '220-You are user number 1 of 10 allowed.\n'
*get* '220-Local time is now 11:47. Server port: 21.\n'
*get* '220-IPv6 connections are also welcome on this server.\n'
*get* '220 You will be disconnected after 10 minutes of inactivity.\n'
*resp* '220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------\n220-You are user number 1 of 10 allowed.\n220-Local time is now 11:47. Server port: 21.\n220-IPv6 connections are also welcome on this server.\n220 You will be disconnected after 10 minutes of inactivity.'
'220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------\n220-You are user number 1 of 10 allowed.\n220-Local time is now 11:47. Server port: 21.\n220-IPv6 connections are also welcome on this server.\n220 You will be disconnected after 10 minutes of inactivity.'
登录服务器
FTP_SESSION_IPv4.login(FTP_USER, FTP_PASSWD)
*cmd* 'USER FTPAnonymous'
*put* 'USER FTPAnonymous\r\n'
*get* '331 User FTPAnonymous OK. Password required\n'
*resp* '331 User FTPAnonymous OK. Password required'
*cmd* 'PASS ************'
*put* 'PASS ************\r\n'
*get* '230 OK. Current restricted directory is /\n'
*resp* '230 OK. Current restricted directory is /'
'230 OK. Current restricted directory is /'
接下来判断文件夹是否存在,创建一个列表用于接收返回值
UPLOAD_DIR_FILES = []
列出文件夹内容,注意这里使用回调函数的方式获取返回值
FTP_SESSION_IPv4.dir(UPLOAD_DIR, UPLOAD_DIR_FILES.append)
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 TYPE is now ASCII\n'
*resp* '200 TYPE is now ASCII'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (192,168,1,30,217,75)\n'
*resp* '227 Entering Passive Mode (192,168,1,30,217,75)'
*cmd* 'LIST /FTPAnonymous/Upload/'
*put* 'LIST /FTPAnonymous/Upload/\r\n'
*get* '150 Accepted data connection\n'
*resp* '150 Accepted data connection'
*get* '226-Options: -a -l \n'
*get* '226 3 matches total\n'
*resp* '226-Options: -a -l \n226 3 matches total'
dir
调用retrlines
实现
FTP_SESSION_IPv4.dir??
Signature: FTP_SESSION_IPv4.dir(*args)
Source:
def dir(self, *args):
'''List a directory in long form.
By default list current directory to stdout.
Optional last argument is callback function; all
non-empty arguments before it are concatenated to the
LIST command. (This *should* only be used for a pathname.)'''
cmd = 'LIST'
func = None
if args[-1:] and type(args[-1]) != type(''):
args, func = args[:-1], args[-1]
for arg in args:
if arg:
cmd = cmd + (' ' + arg)
self.retrlines(cmd, func)
File: c:\programdata\anaconda3\lib\ftplib.py
Type: method
retrlines
回调callback(line)
FTP_SESSION_IPv4.retrlines??
Signature: FTP_SESSION_IPv4.retrlines(cmd, callback=None)
Source:
def retrlines(self, cmd, callback = None):
"""Retrieve data in line mode. A new port is created for you.
Args:
cmd: A RETR, LIST, or NLST command.
callback: An optional single parameter callable that is called
for each line with the trailing CRLF stripped.
[default: print_line()]
Returns:
The response code.
"""
if callback is None:
callback = print_line
resp = self.sendcmd('TYPE A')
with self.transfercmd(cmd) as conn, \
conn.makefile('r', encoding=self.encoding) as fp:
while 1:
line = fp.readline(self.maxline + 1)
if len(line) > self.maxline:
raise Error("got more than %d bytes" % self.maxline)
if self.debugging > 2:
print('*retr*', repr(line))
if not line:
break
if line[-2:] == CRLF:
line = line[:-2]
elif line[-1:] == '\n':
line = line[:-1]
callback(line)
# shutdown ssl layer
if _SSLSocket is not None and isinstance(conn, _SSLSocket):
conn.unwrap()
return self.voidresp()
File: c:\programdata\anaconda3\lib\ftplib.py
Type: method
本例使用list.append
符合retrlines
回调callback(line)
list.append??
Docstring: L.append(object) -> None -- append object to end
Type: method_descriptor
文件夹内容如下
UPLOAD_DIR_FILES
['drwxrwxrwx 2 1002 501 4096 Oct 11 16:04 .',
'drwxrwxrwx 2 1002 501 4096 Oct 11 16:04 ..',
'-rwxrwxrwx 1 1004 501 93696 Oct 13 18:46 python.exe']
不存在文件夹时创建文件夹
if len(UPLOAD_DIR_FILES) == 0 : FTP_SESSION_IPv4.mkd(UPLOAD_DIR)
打开要上传的文件
FILE_READ_HANDLER = open(UPLOAD_FILENAME, 'rb')
上传文件
FTP_SESSION_IPv4.storbinary('STOR ' + UPLOAD_DIR + UPLOAD_BASENAME, FILE_READ_HANDLER)
*cmd* 'TYPE I'
*put* 'TYPE I\r\n'
*get* '200 TYPE is now 8-bit binary\n'
*resp* '200 TYPE is now 8-bit binary'
*cmd* 'PASV'
*put* 'PASV\r\n'
*get* '227 Entering Passive Mode (192,168,1,30,217,37)\n'
*resp* '227 Entering Passive Mode (192,168,1,30,217,37)'
*cmd* 'STOR /FTPAnonymous/Upload/python.exe'
*put* 'STOR /FTPAnonymous/Upload/python.exe\r\n'
*get* '150 Accepted data connection\n'
*resp* '150 Accepted data connection'
*get* '226-File successfully transferred\n'
*get* '226 0.081 seconds (measured here), 1.10 Mbytes per second\n'
*resp* '226-File successfully transferred\n226 0.081 seconds (measured here), 1.10 Mbytes per second'
'226-File successfully transferred\n226 0.081 seconds (measured here), 1.10 Mbytes per second'
storbinary
调用fp.read(blocksize)
获取数据
FTP_SESSION_IPv4.storbinary??
Signature: FTP_SESSION_IPv4.storbinary(cmd, fp, blocksize=8192, callback=None, rest=None)
Source:
def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None):
"""Store a file in binary mode. A new port is created for you.
Args:
cmd: A STOR command.
fp: A file-like object with a read(num_bytes) method.
blocksize: The maximum data size to read from fp and send over
the connection at once. [default: 8192]
callback: An optional single parameter callable that is called on
each block of data after it is sent. [default: None]
rest: Passed to transfercmd(). [default: None]
Returns:
The response code.
"""
self.voidcmd('TYPE I')
with self.transfercmd(cmd, rest) as conn:
while 1:
buf = fp.read(blocksize)
if not buf:
break
conn.sendall(buf)
if callback:
callback(buf)
# shutdown ssl layer
if _SSLSocket is not None and isinstance(conn, _SSLSocket):
conn.unwrap()
return self.voidresp()
File: c:\programdata\anaconda3\lib\ftplib.py
Type: method
本例中文件的read
符合fp.read(blocksize)
要求
FILE_READ_HANDLER.read??
Signature: FILE_READ_HANDLER.read(size=-1, /)
Docstring:
Read and return up to n bytes.
If the argument is omitted, None, or negative, reads and
returns all data until EOF.
If the argument is positive, and the underlying raw stream is
not 'interactive', multiple raw reads may be issued to satisfy
the byte count (unless EOF is reached first). But for
interactive raw streams (as well as sockets and pipes), at most
one raw read will be issued, and a short result does not imply
that EOF is imminent.
Returns an empty bytes object on EOF.
Returns None if the underlying raw stream was open in non-blocking
mode and no data is available at the moment.
Type: builtin_function_or_method
创建一个会话,用于 IPv6 方式连接服务器
FTP_SESSION_IPv6 = ftplib.FTP()
为了演示 FTP 的细节,设置显示更多的调试信息
FTP_SESSION_IPv6.set_debuglevel(2)
按照 IPv6 的地址链接 FTP 服务器,在服务器的欢迎信息中,可以看到连接成功
FTP_SESSION_IPv6.connect(FTP_HOST_IPv6, FTP_PORT)
*get* '220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------\n'
*get* '220-You are user number 2 of 10 allowed.\n'
*get* '220-Local time is now 11:51. Server port: 21.\n'
*get* '220 You will be disconnected after 10 minutes of inactivity.\n'
*resp* '220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------\n220-You are user number 2 of 10 allowed.\n220-Local time is now 11:51. Server port: 21.\n220 You will be disconnected after 10 minutes of inactivity.'
'220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------\n220-You are user number 2 of 10 allowed.\n220-Local time is now 11:51. Server port: 21.\n220 You will be disconnected after 10 minutes of inactivity.'
登录服务器
FTP_SESSION_IPv6.login(FTP_USER, FTP_PASSWD)
*cmd* 'USER FTPAnonymous'
*put* 'USER FTPAnonymous\r\n'
*get* '331 User FTPAnonymous OK. Password required\n'
*resp* '331 User FTPAnonymous OK. Password required'
*cmd* 'PASS ************'
*put* 'PASS ************\r\n'
*get* '230 OK. Current restricted directory is /\n'
*resp* '230 OK. Current restricted directory is /'
'230 OK. Current restricted directory is /'
前面使用dir
列出文件夹,另一种方式是使用nlst
,区别在于dir
使用LIST
命令,返回完整信息,而nlst
使用NLST
命令,返回简要信息。
FTP_SESSION_IPv6.nlst(UPLOAD_DIR)
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 TYPE is now ASCII\n'
*resp* '200 TYPE is now ASCII'
*cmd* 'EPSV'
*put* 'EPSV\r\n'
*get* '229 Extended Passive mode OK (|||55560|)\n'
*resp* '229 Extended Passive mode OK (|||55560|)'
*cmd* 'NLST /FTPAnonymous/Upload/'
*put* 'NLST /FTPAnonymous/Upload/\r\n'
*get* '150 Accepted data connection\n'
*resp* '150 Accepted data connection'
*get* '226-Options: -a \n'
*get* '226 3 matches total\n'
*resp* '226-Options: -a \n226 3 matches total'
['.', '..', 'python.exe']
打开文件用于写入下载的内容
FILE_WRITE_HANDLER = open(os.path.join(os.getcwd(), UPLOAD_BASENAME), 'wb')
下载文件
FTP_SESSION_IPv6.retrbinary('RETR ' + UPLOAD_DIR + UPLOAD_BASENAME, FILE_WRITE_HANDLER.write)
*cmd* 'TYPE I'
*put* 'TYPE I\r\n'
*get* '200 TYPE is now 8-bit binary\n'
*resp* '200 TYPE is now 8-bit binary'
*cmd* 'EPSV'
*put* 'EPSV\r\n'
*get* '229 Extended Passive mode OK (|||55649|)\n'
*resp* '229 Extended Passive mode OK (|||55649|)'
*cmd* 'RETR /FTPAnonymous/Upload/python.exe'
*put* 'RETR /FTPAnonymous/Upload/python.exe\r\n'
*get* '150-Accepted data connection\n'
*get* '150 91.5 kbytes to download\n'
*resp* '150-Accepted data connection\n150 91.5 kbytes to download'
*get* '226-File successfully transferred\n'
*get* '226 0.028 seconds (measured here), 3.19 Mbytes per second\n'
*resp* '226-File successfully transferred\n226 0.028 seconds (measured here), 3.19 Mbytes per second'
'226-File successfully transferred\n226 0.028 seconds (measured here), 3.19 Mbytes per second'
retrbinary
下载数据后调用callback(data)
FTP_SESSION_IPv6.retrbinary??
Signature: FTP_SESSION_IPv6.retrbinary(cmd, callback, blocksize=8192, rest=None)
Source:
def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
"""Retrieve data in binary mode. A new port is created for you.
Args:
cmd: A RETR command.
callback: A single parameter callable to be called on each
block of data read.
blocksize: The maximum number of bytes to read from the
socket at one time. [default: 8192]
rest: Passed to transfercmd(). [default: None]
Returns:
The response code.
"""
self.voidcmd('TYPE I')
with self.transfercmd(cmd, rest) as conn:
while 1:
data = conn.recv(blocksize)
if not data:
break
callback(data)
# shutdown ssl layer
if _SSLSocket is not None and isinstance(conn, _SSLSocket):
conn.unwrap()
return self.voidresp()
File: c:\programdata\anaconda3\lib\ftplib.py
Type: method
而write
符合retrbinary
回调函数的要求
FILE_WRITE_HANDLER.write??
Signature: FILE_WRITE_HANDLER.write(buffer, /)
Docstring:
Write the given buffer to the IO stream.
Returns the number of bytes written, which is always the length of b
in bytes.
Raises BlockingIOError if the buffer is full and the
underlying raw stream cannot accept more data at the moment.
Type: builtin_function_or_method
上一篇: jdbc连接mysql数据库注意事项