Python协议编程之ftp协议、ftblib模块实现上传下载及服务器文件目录等操作

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

ftplib模块

ftplib模块是可以使我们方便的通过程序形式访问并获取对应ftp服务器上内容

属于Python标准库中的内容,不需要额外安装;模块内定义了FTP类及一些相关的功能函数

参考地址:https://docs.python.org/3.6/library/ftplib.html

class ftplib.FTP(host='', user='', passwd='', acct='', timeout=None, source_address=None)
# 返回一个实例化之后的一个新ftp对象
# 当host参数给定时,将自动调用实例中的connect函数连接ftp服务器;
# 当user参数给定时,还会调用实例的login(user,passwd=’’,acct=’’)来连接服务器
'''
host:缺省参数;ftp服务器地址,默认为空字符串。
user:缺省参数;登录用户名
passwd:缺省参数;ftp登录密码,当没有给出时;默认为空字符串。
acct:缺省参数;额外登录信息;默认为空字符串。
timeout:缺省参数;指定连接超时,单位为秒;默认为None。
source_address:缺省参数;绑定来源地址,参数为一个二元组;包含主机地址字符串及整型端口地址(host:str, port:int);默认为None
'''
  • 连接ftp服务器
from ftplib import FTP #导入模块
with FTP('192.168.1.105') as ftp: #连接ftp服务器
    ftp.login() #匿名登录ftp服务器
    print(ftp.dir()) #打印目录下文件及目录
  • ftp实例支持方法
FTP.set_debuglevel (level)
# 设置实例的调试级别
'''
level:调试级别
	0,不输出任何调试信息,同时0也是默认值。
	1:输出每次请求的单行信息。
	2:最高级别调试信息输出,记录每一行发送及接收时的命令
'''

FTP.connect(host='', port=21, timeout=None, source_address=None)
# 连接给定端口及主机地址的ftp服务器

一般很少去指定端口,默认为21端口

对于每一个实例,只需要调用一次即可,如果在使用FTP类创建实例及提供了ftp服务器地址,则不需要调用该函数

可选参数与class ftplib.FTP相同

扫描二维码关注公众号,回复: 13186539 查看本文章

FTP.getwelcome()
# ftp连接之后展示欢迎信息.
# 可以在/etc/vsftpd/vsftpd.conf配置文件中设置ftpd_banner值

FTP.login(user='anonymous', passwd='', acct='')
# 使用给定用户名user登录FTP服务器
# passwd和acct参数为可选参数,默认为空字符串

如果没有指定user参数,默认使用匿名用户访问FTP服务器


FTP.abort()
# 中断文件传输

FTP.sendcmd(cmd)
# 向服务器发送一个简单的命令字符串并返回响应内容字符串

FTP.voidcmd(cmd)
# 向服务器发送一个简单命令字符串并处理响应。如果命令执行成功,则返回空(此时状态码为200-299),否则引发异常(error_reply)

FTP.set_pasv(val)
# 设置ftp是否使用被动模式
'''
val:为True时,启用被动模式;反之,禁用。默认情况下是被动模式
'''

FTP.mlsd(path=’’, facts=[])
# 使用MLSD命令(RFC 3659)以标准格式列出目录
'''
path:访问路径;如果省略,则指定为当前路径。
facts:所需信息的字符串列表,如facts=['type','size','perm'];指明需要获取的目录列表信息为类型
'''

函数返回值为一个二元组

元组中第一个数据为文件名,第二个数据为一个字典,字典内容为获取参数的对应内容


FTP.nlst(path)
# 返回FTP服务器文件名列表
'''
path:要列出的目录,默认为当前服务器目录
'''

FTP.dir(path)
# 生成由列表返回的目录列表,并将其打印到标准输出,返回值在成功时为None
'''
path:控制返回的目录,默认为当前服务器默认目录
'''

FTP.rename(fromname, toname)
# 重命名FTP服务器上的文件名fromname为toname

FTP.delete(filename)
# 删除在FTP服务器上的文件,删除成功,返回响应数据。反之,则抛出异常

FTP.cwd()
# 设置当前FTP操作路径
FTP.mkd()
# 在FTP服务器上创建新的目录

FTP.pwd(pathname)
# 返回当前FTP操作的路径

FTP.rmd(filename)
# 删除FTP服务器上名字为dirname的目录

FTP.size(filename)
# 请求服务器上名为filename文件的大小,成功是返回文件大小,反之返回None。
'''
filename:需要获取的文件名
'''

FTP.quit()
# 发送QUIT命令给服务器并关闭FTP连接。是一个比较温柔的方式中断连接。关闭错误时抛出异常

FTP.close()
# 当前FTP连接,需要注意的是,close不要在quit之后使用造成多次关闭连接

连接FTP

由于FTP实例化后包含上下文管理,具备创建和释放的两个因素

所以我们也可以使用上下文管理语句来方便创建ftp实例并进行连接

def ftp_connect(host,user='anonymous',passwd=''):
    '''
      host: 主机地址
      user: ftp登录用户名
      passwd: ftp登录密码
    '''
    ftp = FTP()
    ftp.connect(host)
    ftp.login(user,passwd) # 默认使用匿名用户登录
    ftp.cwd('pub/') # 切换到对应目录下
    return ftp

目录列表

from ftplib import FTP      # 加载ftp模块
from ftp_connect import ftp_connect

def show_file_list(ftp):
    '''
      字典返回FTP服务器文件及目录
      返回值:
        key: 文件/目录名
        value: 文件类型('dir','file','block')
    '''
    cmd  = 'LIST'
    filelist = {
    
    }
    def get_file(filename):
        file_sig = filename[0]
        file_name = filename.split(' ')[-1]
        sig = {
    
    
            'd': 'dir',
            '-': 'file',
            'b': 'block',
        }
        filelist[file_name] = sig[file_sig]
    try:
      	ftp.retrlines(cmd,get_file)
    except:
      	return None
    else:
      	return filelist

def main():
	host = '192.168.1.100'
	ftp = ftp_connect(host)
	filelist = show_file_list(ftp)
	for name in filelist:
		print('%-12s:%-5s' %(name,filelist[name]))
if __name__ == '__main__':
	main()

通过FTP命令’LIST’以及对应的函数retrlines获取到服务器上目录及文件的列表,其中’LIST’命令返回的FTP服务器上的文件列表内容类似linux下的’ls’命令

通过函数内嵌的get_file()函数对返回字符串进行二次处理,获取到文件名及文件类型。最终函数返回文件名对应文件类型的字典


还可以直接通过ftp.nlst()函数进行更加简单的服务器文件获取工作

from ftplib import FTP      # 加载ftp模块
from ftp_connect import ftp_connect

def main():
    host = '192.168.1.100'
    ftp = ftp_connect(host)
    result = ftp.nlst()
    print(result)

if __name__ == '__main__':
    main()

直接通过使用nlst将返回一个列表数据,列表中的每一个元素为FTP服务器上的文件及目录名

  • 注意:返回结果并不会告知返回文件名的类型

上传文件

FTP.storbinary(cmd, fp, blocksize=8192, callback=None, rest=None)
# 以二进制模式传输上传文件
'''
cmd:STOR命令,如:"STOR filename",指定传输存储文件。
fp:二进制模式打开的本地文件对象。
blocksize:传输数据的最大块大小,默认为8192。
callback:每一次block大小的数据发送之后的回调函数 
rest:与FTP.retrbinary同
'''
FTP.storlines(cmd, fp, callback=None)
# 以ASCII传输模式传输上传文件
'''
cmd:STOR命令,如:"STOR filename"。
fp:二进制模式打开的本地文件对象。
callback:每次发送数据之后的回调函数
'''
  • 上传文件参考
from ftplib import FTP # 加载ftp模块
from ftp_connect import ftp_connect

def upload_file_binary(ftp,filename):
    '''
    filename: 本地需要上传的文件路径
    '''
    cmd = 'STOR ' + filename
    with open(filename, 'rb') as fp:
      ftp.storbinary(cmd,fp)

def upload_file_ascii(ftp,filename):
    '''
    filename: 本地需要上传的文件路径
    '''
    cmd = 'STOR ' + filename
    with open(filename, 'rb') as fp:
      ftp.storlines(cmd,fp)

def main():
    host = '192.168.1.100'
    ftp = ftp_connect(host)
    filename = 'upload.md'
    upload_file_ascii(ftp,filename)
    #upload_file_binary(ftp, filename)

if __name__ == '__main__':
	main()

下载文件

FTP.retrbinary(cmd, callback, blocksize=8192, rest=None)
# 二进制模式传输存储文件;常用在下载FTP服务器上内容
'''
cmd:RETR命令,如:'RETR filename',用来指明下载文件。
callback:每一个接收到的数据块所使用的回调函数,一般为文件对象的写入函数。
blocksize:文件读取传输的最大数据块大小。也是传递给回调函数的最大值。默认为8292。
rest:该参数常用在控制访问文件的字节偏移量。服务器将会重新发送文件字节数据从rest偏移量起
'''
FTP.retrlines(cmd, callback=None)
# ASCII模式传输存储文件;也常用在展示FTP文件目录列表
'''
cmd:参数可以是	RETR或者LIST或NLST;LIST以列表形式检索有关文件及其详细信息。NLST只是以列表展示文件名。
callback:每一行数据所使用的回调函数,默认回调函数将结果打印到标准输出
'''
  • 下载代码参考
from ftplib import FTP # 加载ftp模块
from ftp_connect import ftp_connect

def download_file_binary(ftp,path,filename):
    '''
     二进制模式传输下载文件
     ftp: ftp实例对象
     path: 待下载远程主机文件
     filename: 本地保存文件名
    '''
    cmd = 'RETR ' + path
	with open(filename,'wb') as fp:
    	ftp.retrbinary(cmd,fp.write)

def download_file_acsii(ftp,path,filename):
    '''
    文本模式传输下载文件
    ftp: ftp实例对象
    path: 待下载远程主机文件
    filename: 本地保存文件名
    '''
    cmd = 'RETR ' + path
    with open(filename,'w') as fp:
    	ftp.retrlines(cmd,fp.write)

def main():
    host = '192.168.1.100'
    ftp = ftp_connect(host)
    download_file_acsii(ftp, 'test.md', 'down_file.md')  # ascii模式无法下载具有中文文件
    #download_file_binary(ftp,'test.md','down_file.md')

if __name__ == '__main__':
	main()

下载时,需要我们指明对应服务器上需要下载的文件名在两个下载函数的参数部分我们声明为path然后与’RETR '命令进行拼接,注意这里’RETR '命令后有一个空格;然后分别通过对应ftp实例的 retrlines与retrbinary函数进行下载

猜你喜欢

转载自blog.csdn.net/HeroicLee/article/details/120910651