使用内置的 ftplib 模块在 Python 中使用 LIST、NLST 和 MLSD FTP 命令列出 FTP 服务器中的所有文件和目录,包含一些Python列出FTP文件和目录示例。
Python如何列出FTP文件和目录?FTP(File Transfer Protocol)是标准的网络协议,它使计算机能够传送文件通过网络。在本教程中,你将学习如何连接到 FTP 服务器并列出其上的所有文件和目录,你还将熟悉 Python 的内置ftplib模块及其一些方法。
Python列出FTP服务器所有文件和目录实例介绍:ftplib预装了 Python,所以如果你的机器上安装了 Python,你就可以开始了。打开一个新的 Python 文件并继续,让我们导入教程所需的模块:
import ftplib
import os
from datetime import datetime
在常规 FTP 服务器中,你需要凭据(用户名和密码)才能正确登录,但在本教程中,我们将使用爱丁堡大学的 FTP 服务器,它使用户能够匿名登录:
FTP_HOST = "ftp.ed.ac.uk"
FTP_USER = "anonymous"
FTP_PASS = ""
以下实用函数将帮助我们稍后打印文件和目录列表:
# some utility functions that we gonna need
def get_size_format(n, suffix="B"):
# converts bytes to scaled format (e.g KB, MB, etc.)
for unit in ["", "K", "M", "G", "T", "P"]:
if n < 1024:
return f"{n:.2f}{unit}{suffix}"
n /= 1024
def get_datetime_format(date_time):
# convert to datetime object
date_time = datetime.strptime(date_time, "%Y%m%d%H%M%S")
# convert to human readable date time string
return date_time.strftime("%Y/%m/%d %H:%M:%S")
该get_size_format()
函数是从本教程中抓取的,它基本上将文件的大小从字节转换为更易读的格式,例如1.3MB、103.5KB等。该get_datetime_format()
函数还将日期时间转换为更易读的格式。
现在,让我们使用FTP()
客户端类连接到我们的服务器:
# initialize FTP session
ftp = ftplib.FTP(FTP_HOST, FTP_USER, FTP_PASS)
在编写本教程的代码时,我在处理非拉丁字符时遇到了一些问题,因为 Python 使用ISO-8859-1作为默认编码,因此,让我们将编码更改为UTF-8:
# force UTF-8 encoding
ftp.encoding = "utf-8"
Python列出FTP文件和目录示例 - 现在我们在服务器内部,让我们打印连接后服务器发送的欢迎消息:
# print the welcome message
print(ftp.getwelcome())
这是此服务器的输出:
Welcome to the University of Edinburgh Anonymous FTP server
===========================================================================
When requested for a username enter 'ftp' or 'anonymous'. If you have
problems, try using a dash (-) as the first character of your password.
If you still have problems or wish to make a comment then send email to
ftpmaster@ed.ac.uk.
All transfers are logged.
220 FTP Server
让我们开始调用一些命令,我们要使用的第一个方法是cwd(),它更改当前工作目录,因为我们在根目录中,让我们更改到某个包含一些文件的目录:
# change the current working directory to 'pub' folder and 'maps' subfolder
ftp.cwd("pub/maps")
列出文件和目录:
# LIST a directory
print("*"*50, "LIST", "*"*50)
ftp.dir()
这是输出的一部分:
************************************************** LIST **************************************************
-rw-r--r-- 1 1407 bin 25175 Jul 8 1991 JIPS-map.910704-1.ps.Z
-rw-r--r-- 1 1407 bin 25714 Jul 30 1991 JIPS-map.910730-1.ps.Z
-rw-r--r-- 1 1407 bin 25980 Aug 2 1991 JIPS-map.910802-1.ps.Z
-rw-r--r-- 1 1407 bin 26812 Aug 7 1991 JIPS-map.910806-1.ps.Z
-rw-r--r-- 1 1407 bin 26673 Oct 11 1991 JIPS-map.911011-1.ps.Z
...<SNIPPED>...
Python如何列出FTP文件和目录?与ls
命令提供的输出非常相似。但是,这使用了LIST
现在已经过时的 FTP命令。此外,你可能已经注意到,它不返回任何值,它只是将当前工作目录中的目录和文件打印到屏幕上。
另一种选择是使用NLST
命令:
# NLST command
print("*"*50, "NLST", "*"*50)
print("{:20} {}".format("File Name", "File Size"))
for file_name in ftp.nlst():
file_size = "N/A"
try:
ftp.cwd(file_name)
except Exception as e:
ftp.voidcmd("TYPE I")
file_size = get_size_format(ftp.size(file_name))
print(f"{file_name:20} {file_size}")
输出:
************************************************** NLST **************************************************
File Name File Size
backbone.t3-ps.Z 23.39KB
backbone.t1t3-ps.Z 24.56KB
ripe-map06-netnums.ps.Z 29.54KB
edlana4bw.ps.Z 63.34KB
...<SNIPPED>...
但是,正如你所看到的,该NLST
命令仅返回文件和目录的名称,没有别的,我们想要一些可以为我们提供名称列表及其元数据的东西,例如权限、大小、上次修改日期等。
Python列出FTP文件和目录示例 - 在这里,我们使用MLSD
进入救援的命令:
print("*"*50, "MLSD", "*"*50)
# using the MLSD command
print("{:30} {:19} {:6} {:5} {:4} {:4} {:4} {}".format("File Name", "Last Modified", "Size",
"Perm","Type", "GRP", "MODE", "OWNER"))
for file_data in ftp.mlsd():
# extract returning data
file_name, meta = file_data
# i.e directory, file or link, etc
file_type = meta.get("type")
if file_type == "file":
# if it is a file, change type of transfer data to IMAGE/binary
ftp.voidcmd("TYPE I")
# get the file size in bytes
file_size = ftp.size(file_name)
# convert it to human readable format (i.e in 'KB', 'MB', etc)
file_size = get_size_format(file_size)
else:
# not a file, may be a directory or other types
file_size = "N/A"
# date of last modification of the file
last_modified = get_datetime_format(meta.get("modify"))
# file permissions
permission = meta.get("perm")
# get the file unique id
unique_id = meta.get("unique")
# user group
unix_group = meta.get("unix.group")
# file mode, unix permissions
unix_mode = meta.get("unix.mode")
# owner of the file
unix_owner = meta.get("unix.owner")
# print all
print(f"{file_name:30} {last_modified} {file_size:7} {permission:5} {file_type:4} {unix_group:4} {unix_mode:4} {unix_owner}")
我们使用调用 FTP命令的mlsd()方法MLSD
,它返回一个包含文件名和文件元数据的元组,我们提取所有内容并将它们打印到屏幕上。请注意,我使用TYPE I
命令将传输类型更改为二进制图像,这是因为如果不是这种情况,size()将引发异常。
Python如何列出FTP文件和目录?我们还使用我们之前定义的函数get_datetime_format()将 FTP 服务器返回的日期转换为更易读的格式,这里是上述配方的截断输出:
************************************************** MLSD **************************************************
File Name Last Modified Size Perm Type GRP MODE OWNER
backbone.t3-ps.Z 1991/07/30 11:28:13 23.39KB adfr file 1 0644 1407
backbone.t1t3-ps.Z 1991/07/30 11:28:41 24.56KB adfr file 1 0644 1407
ripe-map06-netnums.ps.Z 1991/07/08 09:57:23 29.54KB adfr file 1 0644 1407
edlana4bw.ps.Z 1992/06/17 13:30:40 63.34KB adfr file 2005 0644 1407
...<SNIPPED>...
MLSD
命令是格式化目录列表的当前 FTP 标准,它是在RFC 3659上引入的。
Python列出FTP服务器所有文件和目录 - 最后,在使用 FTP 服务器后,是时候退出并关闭连接了:
# quit and close the connection
ftp.quit()
好了,教程到此结束。你现在不应该使用LIST
command (在 Python 中使用dir()方法),这MLSD
是要走的路,即使某些 FTP 服务器仍然不支持MLSD
,NLST
command 仍然是一种替代方法。