ホームページ >バックエンド開発 >Python チュートリアル >Python ファイルとディレクトリの操作および圧縮モジュール (os、zipfile、tarfile、shutil)
ファイルやディレクトリの操作に使用できる Python の組み込みモジュールには次のものが含まれます:
モジュール/関数名 | 関数の説明 |
---|---|
open() 関数 | ファイルの読み取りまたは書き込み |
os.pathモジュール | ファイルパス操作 |
osモジュール | ファイルとディレクトリの簡単な操作 |
zipfileモジュール | ファイル圧縮 |
tarfileモジュール | ファイルパッケージ化 |
シュティルモジュール | 高度なファイルとディレクトリの処理 |
fileinput モジュール | 1 つ以上のファイルのすべての行を読み取る |
tempfile モジュール | ファイルが読み取られるか書き込まれる一時ファイルとディレクトリを作成する |
エントリについては以前の記事で説明していますので、詳しくはこちらをご覧ください。ここでは主に他のいくつかのモジュールについて説明します。
os.path モジュールは主に、パスの分割と結合、ファイルの相対パスと絶対パスの取得、および対応するファイルの取得などのファイル パスの操作に使用されます。ファイル パスの時間属性、ファイル パスに対応するファイルの種類の決定、2 つのパスが同じファイルかどうかの決定など。
# 返回指定文件的绝对路径名 os.path.abspath(path) # 将路径名称分割成两部分(head, tail),tail是路径名称path中的最后一部分且不包含斜线(路径风格符),head是tail之前的所有部分;如果path以斜线结尾则 tail为空字符串,如果path中没有斜线则head为空字符串 os.path.split(path) # 将路径名称分割成两部分(root, ext), ext表示后缀名 os.path.splitext(path) # 返回path路径名的基名称,实际上就是os.path.split(path)函数返回值的第二个值 os.path.basename(path) # 返回path路径名的目录名称,实际上就是os.path.split(path)函数返回值的第一个值 os.path.dirname(path) # 将一个或多个路径中的非空值通过路径分隔符拼接成一个新的路径名称,如果在拼接过程中遇到绝对路径将会丢弃前面的部分并从该绝对路径重新开始拼接 os.path.join(path, *paths) # 指定的文件路径存在则返回Ture,否则返回False。如果是失效的链接文件则返回False os.path.exists(path) # 返回该路径对应文件的最近一次访问时间的时间戳(秒),如果文件不存在或无法访问,则引发OSError os.path.getatime(path) # 返回该路径对应文件的最后修改时间的时间戳(秒),如果文件不存在或无法访问,则引发OSError os.path.getmtime(path) # 返回该路径对应文件的ctime,在某些系统上(如Unix上)是最后一次元数据更改时间,在其他系统上(如Windows)是路径的创建时间;如果文件不存在或无法访问,则引发OSError os.path.getctime(path) # 返回指定路径对应文件的字节大小 os.path.getsize(path) # 返回path相对于start的相对路径 os.path.relpath(path, start=os.curdir) # 获取path的真实、绝对路径(可用于获取软链接文件指向的文件路径) os.path.realpath(path) # 判断path是否是绝对路径,是则返回True,否则返回False os.path.isabs(path) # 判断path是否是一个文件 os.path.isfile(path) # 判断path是否是一个目录 os.path.isdir(path) # 判断path是否是一个链接 os.path.islink(path) # 判断path是否是一个挂载点 os.path.ismount(path) # 判断path1和path2是否为同一个文件 os.path.samefile(path1, path2)
注: os.path.basename(path) 関数と Unix の Basename プログラムの違いは、path がパス区切り文字 (' など) で終わる場合です。 /usr /local/')、basename(path) の戻り値は空の文字列 ('')、basename プログラムの戻り値は最後から 2 番目のパス区切り文字
>>> import os >>> >>> os.path.abspath('test.sh') '/root/test.sh' >>> os.path.split('/root/test.sh') ('/root', 'test.sh') >>> os.path.split('/usr/local') ('/usr', 'local') >>> os.path.split('/usr/local/') ('/usr/local', '') >>> os.path.split('test.sh') ('', 'test.sh') >>> os.path.basename('/root/test.sh') 'test.sh' >>> os.path.dirname('/root/test.sh') '/root' >>> os.path.splitext('test.sh') ('test', '.sh') >>> os.path.splitext('/root/test.sh') ('/root/test', '.sh') >>> os.path.splitext('/usrl/local') ('/usrl/local', '') >>> os.path.join('/root') '/root' >>> os.path.join('/root', '1', '', '2', ' ', '3' ) '/root/1/2/ /3' >>> os.path.join('/root', '/usr/local', 'test.sh') '/usr/local/test.sh' >>> os.path.join('/root', '/usr/local', '1', '') '/usr/local/1/' >>> os.path.exists('/root/test.sh') True >>> os.path.exists('/root/test.txt') False >>> os.path.exists('/etc/rc0.d') True >>> os.path.getatime('/etc/my.cnf') 1483433424.62325 >>> os.path.getmtime('/etc/my.cnf') 1472825145.4308648 >>> os.path.getctime('/etc/my.cnf') 1472825145.432865 >>> os.path.relpath('/etc/my.cnf') '../etc/my.cnf' >>> os.path.relpath('/etc/my.cnf', start='/etc') 'my.cnf >>> os.path.realpath('/etc/rc0.d') '/etc/rc.d/rc0.d' >>> os.path.realpath('test.sh') '/root/test.sh' >>> os.system('ls -l /etc/my.cnf') -rw-r--r-- 1 root root 597 Sep 2 22:05 /etc/my.cnf >>> os.path.getsize('/etc/my.cnf') 597 >>> os.path.isabs('/etc/my.cnf') True >>> os.path.isabs('my.cnf') False >>> os.path.isfile('/etc/my.cnf') True >>> os.path.isdir('/etc/my.cnf') False >>> os.path.islink('/etc/my.cnf') False >>> os.path.islink('/etc/rc0.d') True >>> os.path.islink('/etc/rc0.d/') False >>> os.path.isdir('/etc/rc0.d/') True >>> os.path.isdir('/etc/rc0.d') True >>> os.system('df -Th') Filesystem Type Size Used Avail Use% Mounted on /dev/vda1 ext4 40G 8.7G 29G 24% / devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs tmpfs 3.9G 401M 3.5G 11% /run tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup tmpfs tmpfs 783M 0 783M 0% /run/user/0 0 >>> os.path.ismount('/') True >>> os.path.ismount('/dev') True >>> os.path.ismount('/usr') False >>> os.path.samefile('/etc/rc0.d', '/etc/rc0.d') True >>> os.path.samefile('/etc/rc0.d', '/etc/rc0.d/') True
説明が必要です: OS モジュールは、さまざまなオペレーティング システム関連の機能を提供する、混合オペレーティング システム インターフェイス モジュールです。ファイルとディレクトリ 操作はその一部であり、すべてではありません。
一部の Unix プラットフォームでは、このモジュールの多くのファイルまたはディレクトリ操作関数は、次の機能の 1 つ以上をサポートしています:
ファイル記述子を指定します 一部の関数では、path パラメーターは、次の機能だけでなく、文字列またはファイル記述子のみ。この関数は、このファイル記述子によって参照されるファイルに対して動作します。 os.supports_fd を使用して、現在のプラットフォーム パス パラメーターをファイル記述子として指定できるかどうかを確認できます。それが使用できない場合は、NotImplementedError が発生します。関数が dir_fd または follow_symlinks パラメーターもサポートしている場合、パスがファイル記述子として指定されているときに dir_fd または follow_symlinks パラメーターを指定するとエラーになります。
ディレクトリ記述子に対する相対パス dir_fd が None でない場合、それはディレクトリを指すファイル記述子である必要があり、パスの場合、操作対象のパスはディレクトリに対する相対パスである必要があります。が絶対パスの場合、dir_fd は無視されます。
シンボリックリンクをたどらないでください follow_symlinks が False で、操作対象のパス内の最後の要素がシンボリック リンクである場合、この関数は、リンクされたファイルが指すファイルではなく、リンクされたファイルに対して操作します。 。
# 测试当前用户是否对path所对应文件有某种访问权限 # Python2 os.access(path, mode) # Python3 os.access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True) # 更改当前工作目录,从Python3.3开始path参数允许是一个目录的文件描述符 os.chdir(path) # 更改当前工作目录,从Python3.3开始该函数等价于os.chdir(fd) os.chfdir(fd) # 更改文件或目录权限,dir_fd和follow_symlinks是Python3.3新增的参数 os.chmod(path, mode, *, dir_fd=None, follow_symlinks=True) # 更改文件或目录权限,如果path是个链接文件则影响是链接文件本身;Python3.3开始该函数等价于os.chmod(path, mode, follow_symlinks=False) os.lchmod(path, mode) # 更改文件或目录的属主和属组,如果不改变则设置为-1;dir_fd和follow_symlinks是Python3.3新增的参数 os.chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True) 更改文件或目录的属主和属组,如果不改变则设置为-1;如果path是个链接文件则影响是链接文件本身;Python3.3开始该函数等价于os.chown(path, uid, gid, follow_symlinks=False) os.lchown(path, uid, gid) # 更改当前进程主目录 os.chroot(path) # 返回一个表示当前目录的字符串 os.getcwd() # 返回一个表示当前目录的字节串,Python3新添加的函数 os.getcwdb() # 创建硬链接, *后面的参数都是Python3.3新增的 os.link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True) # 创建软链接,*后面的参数都是Python3.3新增的 os.symlink(src, dst, target_is_directory=False, * dir_fd=None) # 返回指定目录中所有文件列表,顺序不固定,且不包含‘.’和‘..’;注意path在Python2中没有默认值 os.listdir(path='.') # 返回指定目录中所有文件条目对应的DirEntry对象迭代器,顺序不固定,则不包含'.'和‘..’;Python3.5新增的函数 os.scandir(path='.') # 获取文件或文件描述的状态信息,染回一个stat_result对象,dir_fd和follow_symlinks都是Python3.3新增的参数 os.stat(path, *, dir_fd=None, follow_symlinks=True) # 获取文件或文件描述的状态信息,如果path是一个链接文件则获取的是链接文件本身的状态信息;Python3.3开始,该函数等价于os.stat(path, dir_fd=dir_fd, folow_symlinks=False) os.lstat(path, *, dir_fd=None) # 创建一个名为path的目录并指定目录权限,如果目录已经存在则会引起FileExistsError;dir_fd是Python3.3开始新加的参数。需要说明的是该函数与os.makedirs()、os.mkfifo()函数创建的目或逛到文件的权限会受到umask的影响,比如指定mode为0777,实际目录权限为 0777 - umask = 0755 os.mkdir(path, mode=0o777, *, dir_fd=None) # 递归创建目录,该函数功能与mkdir()相似,但是会递归创建所有的中间目录;exist_ok为Python3.2新增参数,表示当目录已经存在时是否正常返回,如果exist_ok为False(默认)且目标目录已经存在则会引发OSError os.makedirs(name, mode=0o777, exists_ok=False) # 创建一个FIFO(命名管道)文件,FIFO可以被当做正常文件那样访问;通常FIFOs被用作‘client’和‘server’类型进程的汇集点,server打开FIFO读取数据,client打开FIFO写入数据。 os.mkfifo(path, mode=0o666, *, dir_fd=None) # 删除指定的文件,如果path是个目录将会引发OSError os.remove(path, *, dir_fd=None) os.unlink(path, *, dir_fd=None) # 删除指定的空目录,如果目录不为空会引发OSError os.rmdir(path, *, dir_fd=None) # 递归删除指定路径中的所有空目录 os.removedirs(name) # 目录或文件重命名,如果dst是一个目录见鬼引发OSError。在Unix平台上,如果dst存在且是一个文件,那么只要用户有权限就将会被静默替换;而在Windows平台上,如果dst存在,即使它是一个文件也会引发OSError os.rename(src, dst, *, src_dir_fd=-None, dst_dir_fd=None) # 目录或文件递归重命名 os.renames(old, new) # 与os.rename()功能相同,区别在于:对于os.replace()来说,如果dst存在且是一个文件,那么只要用户有权限就将会被静默替换,而没有平台上的差别 os.replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None) # 返回链接文件指向的真实路径,类似于os.path.relpath(path),但是该方法可能返回相对路径 os.readlink(path, *, dir_fd=None) # 返回一个文件的某个系统配置信息,name表示配置项名称,可以通过os.pathconf_names来查看可用的值 os.pathconf(path, name)
os.access() 関数の説明: デフォルトでは、ユーザーの実 uid (RUID) と gid がファイル アクセス許可の検出に使用されますが、ほとんどの操作は有効な uid (EUID) または gid が検出に使用されます。Python3 では、effective_ids パラメーターを True に設定することで、権限の検出に有効な uid/gid を使用できます (RUID/EUID/SUID の概念については、a8093152e673feb7aba1828c43532094を参照してください)。 ;
)。 mode の可能な値は、os.F_OK (ファイルが存在する)、os.R_OK (読み取り可能)、os.W_OK (書き込み可能)、os.X_OK (実行可能) のいずれか、または論理演算子で接続された複数の値です。
>>> import os >>> >>> os.access('/bin/passwd', os.F_OK) True >>> os.access('/bin/passwd', os.F_OK|os.X_OK) True >>> os.access('/bin/passwd', os.F_OK|os.W_OK) True >>> os.getcwd() '/root' >>> os.chdir('/tmp') >>> os.getcwd() '/tmp' >>> os.system('ls -l test*') -rw-r--r-- 1 root root 0 Feb 9 09:02 test1.txt lrwxrwxrwx 1 root root 9 Feb 9 09:02 test.txt -> test1.txt 0 >>> os.chmod('/tmp/test.txt', 0666) >>> os.system('ls -l test*') -rw-rw-rw- 1 root root 0 Feb 9 09:02 test1.txt lrwxrwxrwx 1 root root 9 Feb 9 09:02 test.txt -> test1.txt 0 >>> os.link('test.txt', 'test') >>> os.system('ls -li test*') 271425 lrwxrwxrwx 2 root root 9 Feb 9 09:02 test -> test1.txt 271379 -rw-rw-rw- 1 mysql mysql 0 Feb 9 09:02 test1.txt 271425 lrwxrwxrwx 2 root root 9 Feb 9 09:02 test.txt -> test1.txt 0 >>> os.listdir('.') ['zabbix_proxy.log', 'test.txt', 'zabbix_agentd.log', '.Test-unix', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-systemd-machined.service-gJk0Cd', 'hsperfdata_root', 'wrapper-31124-1-out', 'a', 'test1.txt', 'zabbix_proxy.log.old', 'zabbix_agentd.log.old', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-mariadb.service-kudcMu', 'test', '.X11-unix', '.font-unix', 'wrapper-31124-1-in', '.XIM-unix', '.ICE-unix', 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>'] >>> os.listdir('/tmp') ['zabbix_proxy.log', 'test.txt', 'zabbix_agentd.log', '.Test-unix', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-systemd-machined.service-gJk0Cd', 'hsperfdata_root', 'wrapper-31124-1-out', 'a', 'test1.txt', 'zabbix_proxy.log.old', 'zabbix_agentd.log.old', 'systemd-private-14bb029ad4f340d5ac49a6fb3c2ca6c9-mariadb.service-kudcMu', 'test', '.X11-unix', '.font-unix', 'wrapper-31124-1-in', '.XIM-unix', '.ICE-unix', 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)>'] >>> os.mkdir('/tmp/testdir') >>> os.system('ls -l /tmp') lrwxrwxrwx 2 root root 9 Feb 9 09:02 test -> test1.txt -rw-rw-rw- 1 mysql mysql 0 Feb 9 09:02 test1.txt drwxr-xr-x 2 root root 4096 Feb 9 09:47 testdir lrwxrwxrwx 2 root root 9 Feb 9 09:02 test.txt -> test1.txt >>> os.mkdir('/tmp/testdir') Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 17] File exists: '/tmp/testdir' >>> os.mkdir('/tmp/a/b/c') Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 2] No such file or directory: '/tmp/a/b/c' >>> os.makedirs('/tmp/a/b/c') # mode默认为0777,结果却是0755,bug? >>> os.makedirs('/tmp/b/c/d', 0700) >>> os.system('ls -l /tmp') total 2316 drwxr-xr-x 3 root root 4096 Feb 9 10:16 a drwx------ 3 root root 4096 Feb 9 10:16 b lrwxrwxrwx 2 root root 9 Feb 9 09:02 test -> test1.txt -rw-rw-rw- 1 mysql mysql 0 Feb 9 09:02 test1.txt drwxr-xr-x 2 root root 4096 Feb 9 09:47 testdir lrwxrwxrwx 2 root root 9 Feb 9 09:02 test.txt -> test1.txt >>> os.rename('/tmp/test1.txt', '/tmp/test3.txt') >>> os.system('ls -l /tmp') lrwxrwxrwx 2 root root 9 Feb 9 09:02 test -> test1.txt prw-r--r-- 1 root root 0 Feb 9 10:21 test1.fifo -rw-rw-rw- 1 mysql mysql 0 Feb 9 09:02 test3.txt drwxr-xr-x 2 root root 4096 Feb 9 09:47 testdir prw-r--r-- 1 root root 0 Feb 9 10:20 test.fifo lrwxrwxrwx 2 root root 9 Feb 9 09:02 test.txt -> test1.txt >>> os.readlink('/tmp/test.txt') 'test1.txt' >>> os.rmdir('/tmp/testdir') >>> os.rmdir('/tmp/a/b/c') # 只删除空目录/tmp/a/b/c >>> os.removedirs('/tmp/b/c/d') # 先删除空目录/tmp/a/b/c,然后删除空目录/tmp/a/b,最后删除目录/tmp/a,而目录/tmp非空,因此不会被删除 >>> os.unlink('/tmp/test') >>> os.unlink('/tmp/test.fifo') >>> os.unlink('/tmp/test.txt') >>> os.system('ls -l /tmp') >>> os.remove('/tmp/test3.txt') >>> os.remove('/tmp/test1.fifo')
説明 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ZIPファイルの読み書きに使用 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Pythonライブラリを含むZIPアーカイブの作成に使用 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
は、アーカイブファイル内のメンバー情報を表すために使用されます |
関数/定数名 | 説明 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
zipfile.is_zipfile(filename) | filenameが有効なZIPファイルかどうかを判断し、値を返しますブール型の | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zipfile.ZIP_STORED | は、圧縮されたアーカイブ メンバー | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zipfile.ZIP_DEFLATED | を表し、zlib モジュールのサポートが必要な通常の ZIP 圧縮方法 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zipfile.ZIP_BZIP2 | BZIP2 圧縮方式には bz2 モジュールのサポートが必要であることを意味します。Python3.3 では | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zipfile.ZIP_LZMA | が追加され、LZMA 圧縮方式では lzma モジュールのサポートが必要になります。3. zipfile.ZipFile类类的构造方法class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True) 创建一个ZipFile实例,表示打开一个ZIP文件。 参数:
说明:
实例方法列表# 打印该归档文件的内容 printdir() # 从归档文件中展开一个成员到当前工作目录,memeber必须是一个完整的文件名称或者ZipInfo对象,path可以用来指定一个不同的展开目录,pwd用于加密文件的密码 extract(memeber, path=None, pwd=None) # 从归档文件展开所有成员到当前工作目录,path和pwd参数作用同上,memebers必须是namelist()返回的list的一个子集 extractall(path=None, members=None, pwd=None) # 返回一个与每一个归档成员对应的ZipInfo对象的列表 infolist() # 返回归档成员名称列表 namelist() # 返回一个包含压缩成员name相关信息的ZipInfo对象,如果name没有被包含在该压缩文档中将会引发KeyError getinfo(name) # 将归档文件中的一个成员作为一个file-like对象展开;name是归档文件中的文件名或者一个ZipInfo对象 open(name, mode='r', pwd=None) # 关闭该压缩文件;退出程序前必须调用close()方法,否则一些必要记录不会被写入 close() # 设置pwd作为展开加密文件的默认密码 setpassword(pwd) # 读取归档文件中所有文件并检查它们的完整性,返回第一个被损坏的文件名称,或者None。对已关闭的ZipFile调用testzip()将会引发RuntimeError testzip() # 返回归档文件中name所指定的成员文件的字节。name是归档文件中的文件名称或一个ZipInfo对象。该归档文件必须以读(r)或追加(a)的模式打开。如果设置了pwd参数,则其将会覆盖setpassword(pwd)方法设置的默认密码。对一个已经关闭的ZipFile调用read()方法将会引发RuntimeError read(name, pwd=Noneds) # 将filename文件写入归档文件,可以通过arcname指定新文件名(需要注意的是文件名中磁盘盘符和开头的路径分隔符都会被移除);compress_type表示压缩方法,如果指定了该参数则会覆盖ZipFile构造方法中的compression参数指定的值;要调用此方法,归档文件必须以'w', 'a'或'x'模式打开,如果对以'r'模式打开的ZipFile调用write()方法或者对已关闭的ZipFile调用write()方法将会引发RuntimeError write(filename, arcname=None, compress_type=None) # 将一个字节串写入归档文件;zinfo_or_arcname可以是归档文件中的文件名称,也可以是一个ZipInfo实例 writestr(zinfo_or_arcname, bytes[, compress_type]) 4. zipfile.PyZipFile类PyZipFile类用于创建包含Python库的ZIP存档 类的构造方法PyZipFile的构造方法与ZipFile的构造方法参数基本一致,只是多了一个optimize参数 class zipfile.PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, optimize=-1) 说明:
实例方法列表PyZipFile类的实例方法与ZipFile类的实例方法一致,只是多了一个writepy()方法: # 搜索*.py文件并将相应的文件添加到归档文件 writepy(pathname, basename='', filterfunc=None) 说明:
5. zipfile.ZipInfo类ZipInfo类的实例时通过ZipFile对象的getinfo()和infolist()方法返回的,其本身没有对外提供构造方法和其他方法。每一个ZipInfo对象存储的是ZIP归档文件中一个单独成员的相关信息,因此该实例仅仅提供了以下属性用于获取归档文件中成员的信息。
6. 实例实例1:文件归档与解压缩操作import zipfile # 归档 z = zipfile.ZipFile('test.zip', 'w') z.write('a.txt') z.write('b.log') z.close() # 解压 z = zipfile.ZipFile('test.zip', 'r') z.extractall() z.close() # 文件信息读取 z = zipfile.ZipFile('test.zip', 'r') z.printdir() z.namelist() z.infolist() zinfo = z.getinfo('a.txt') print(zinfo.filename) print(zinfo.date_time) print(zinfo.file_size) print(zinfo.compress_size) z.close() 实例2:python文件归档工程目录结构 MYPROG │ hello.py │ ├─account │ login.py │ __init__.py │ ├─test │ test_print.py │ └─tools tool.py 代码 import zipfile pyz = zipfile.PyZipFile('myprog.zip', 'w') pyz.writepy('MYPROG/hello.py') pyz.writepy('MYPROG/tools') pyz.writepy('MYPROG/test') pyz.writepy('MYPROG/account') pyz.close() pyz.printdir() 输出结果: File Name Modified Size hello.pyc 2017-02-16 11:46:20 130 tool.pyc 2017-02-16 11:55:44 135 test_print.pyc 2017-02-16 11:55:48 140 account/__init__.pyc 2017-02-16 11:55:54 118 account/login.pyc 2017-02-16 11:55:54 138 四、文件打包(tarfile模块)tarfile模块用于读写tar归档文件,它也可以同时实现压缩功能。与zipfile模块相比,tarfile模块 可以直接将一个目录进行归档并压缩。另外,tarfile模块提供的api更“面向对象”化。 1. tarfile模块包含的两个主要的类
这两个类的关系类似于zipfile.ZipFile与zipfile.ZipInfo的关系,TarInfo对象中保存了一个文件所需要的所有属性,比如:文件类型、文件大小、修改时间、权限、属主等,但是它不包含文件的数据。 2.tarfile模块包含的方法和常量
关于open()函数的说明: tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs) 该函数用于创建并返回一个TarFile对象。Python官方文档不建议直接使用TarFile的构造方法构建示例,而是建议使用这个open()函数来操作TarFile对象。下面我们来说说它的参数:
下面是mode所有可取值的列表:
对于 'w:gz', 'r:gz', 'w:bz2', 'r:bz2', 'x:gz', 'x:bz2'这些模式, tarfile.open() 接收关键字参数 compresslevel (默认值为9) 来指定该归档文件的压缩级别. 3.tarfile.TarFile类类构的造方法class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=0) 参数说明:
类方法classmethod TarFile.open(...) 这是个可选的构造方法,实际上tarfile.open()函数就是这个函数的快捷方式 实例方法# 将name文件添加到归档;name可以是任何类型的文件(如:目录,fifo管道,软连接等),arcname用于指定name文件被添加到归档后的新名字,arcname默认为None,表示文件名称保持不变。recursive值为Trur表示如果name文件是一个目录,则该目录中文件会被递归添加到归档中。exclude参数如果被指定,则其值必须是一个接受文件名作为参数的函数,且该函数必须返回一个布尔值,返回值为True表示该文件将不会被添加到归档中,反之则会被添加到归档中。filter参数如果被提供,则它必须是一个关键字参数且它应该是一个接收TarInfo对象作为参数的函数,该函数应该返回被修改后的TarInfo对象;如果它的返回值为None,那么该TarInfo将不会被添加到归档中。需要说明的是,从Python 3.2开始 exclude参数被废弃,新增filter参数,且使用filter代替exclude的功能 add(name, arcname=None, recursive=True, exclude=None, *, filter=None) # 添加指定TarInfo对象到归档中。如果fileobj被提供,它应该是一个二进制文件,且会从这个二进制文件中读取tarinfo.size字节的内容添加到这个归档中。你可以通过gettarinfo()直接创建TarInfo对象 addfile(tarinfo, fileobj=None) # 返回归档成员name对应的TarInfo对象(类似zipfile.ZipFile实例的getinfo(name)方法);如果name无法在归档中找到会引发KeyError,如果一个成员在归档中不仅出现一次,则最后一次出现将被当做最新版本 getmemeber(name) # 将归档中所有成员作为TarInfo对象的列表返回(类似zipfile.ZipFile实例的infolist()方法) getmemebers() # 将归档中所有成员的名称以列表形式返回(类似zipfile.ZipFile实例的namelist()方法) getnames() # 打印内容列表到sys.stdout(类似zipfile.ZipFile实例的printdir()方法);如果verbose值为False,则仅打印成员的名称;如果verbose值为True,则打印的内容类似'ls -l'命令的输出;如果可选参数members被给出,它必须是getmembers()方法返回的列表的子集;Python 3.5新增memebers参数 list(verbose=True, *, memebers=None) # (当以读模式打开归档时)该方法以TarInfo对象的形式返回归档的下一个成员,如果已经没有可用的成员则返回None next() # 将归档中的所有成员提取到当前工作目录或path参数指定的目录;如果memebers参数被指定,它必须是getmemebers()函数返回列表的子集;所有者、更改时间和权限等目录信息会在所有成员被提取后设置;如果numberic_owner值为True,将使用tarfile的uid和gid数字来设置提取后文件的属主和属组,否则将使用叔叔和属组的名字。Python 3.5中新增了number_owner参数 extractall(path=".", memebers=None, *, numeric_owner=False) # 提取归档中的一个成员到当前工作目录或path指定的目录,member参数的值可以是一个文件名或一个TarInfo对象;Python 3.2添加了set_attrs参数,Python 3.5添加了numberic_owner参数 extract(member, path="", set_attrs=True, *, numberic_owner=False) # 提取归档中的一个成员为一个文件对象,member参数的值可以是一个文件名或一个TarInfo对象;从Python 3.3开始,如果member是一个普通文件或是一个链接,该方法会返回一个io.BufferedReader对象,否则会返回None extractfile(member) # 通过对现有文件执行os.stat()操作的结果创建一个TarInfo对象;这个已存在的文件可以通过文件名name来指定,也而已通过文件对象fileobj来指定(文件描述符),文件被添加到归档后的文件名取值优先级为:arcname参数的值,fileobj.name属性的值,name参数的值;你可以在通过addfile()方法将该文件添加到归档之前对TarInfo对象的一些属性值进行修改 gettarinfo(name=None, arcname=None, fileobj=None) # 关闭TarFile对象 close() 4. tarfile.TarInfo类一个TarInfo对象表示TarFile中的一个成员。TarInfo对象中除了保存了一个文件所需要的所有属性(比如:文件类型、文件大小、修改时间、权限、属主等)之外,它还提供了一些用于判断其文件类型的方法。需要注意的是,它不包含文件的数据。TarInfo对象可以通过TarFile的getmember()、getmembers()和gettarinfo()方法获取。 类构造方法class tarfile.TarInfo(name="") 类方法# 从字符串缓冲区创建一个TarInfo对象并返回 classmethod TarInfo.frombuf(buf, encoding, errors) 从TarFile对象中读取一个成员并将其作为一个TarInfo对象返回 classmethod TarInfo.fromtarfile(tarfile) 对象方法和属性
5. 实例工程目录结构: MYPROG │ hello.py │ ├─account │ login.py │ __init__.py │ ├─test │ test_print.py │ └─tools tool.py Python工程归档及解压操作: import tarfile # 归档压缩 tf = tarfile.open('myprog.tar.gz', 'w:gz') tf.add("MYPROG") tf.close() # 解压 tf = tarfile.open('myprog.tar.gz') tf.extractall() tf.close() # 读取归档文件内容 tf = tarfile.open('myprog.tar.gz') tf.list() print(tf.getmembers()) f = tf.getmember('MYPROG/hello.py') print(f.name) print(f.size) f.isfile() tf.close() 五、高级文件和目录处理(shutil模块)上面我们介绍了路径操作(os.path模块)、文件和目录操作(os模块)和 文件归档压缩操作(zipfile模块和tarfile模块),但是还是这些模块要么缺少一些常用的功能(如:文件复制、删除非空文件夹),要么使用起来不是那么方便,而shutil模块shutil提供了一些文件和文件集合的高级操作,可以弥补这些不足。
1. 文件和目录操作# 文件内容(部分或全部)复制,参数是两个已经打开的文件对象;length是一个整数,用于指定缓冲区大小,如果其值是-1表示一次性复制,这可能会引起内存问题 shutil.copyfileobj(fsrc, fdst[, length]) # 文件内容全部复制(不包括metadata状态信息), 参数是两个文件名,且dst必须是完整的目标文件名称;如果dst已经存在则会被替换;follow_symlinks是Python 3.3新增的参数,且如果它的值为False则将会创建一个新的软链接文件 shutil.copyfile(src, dst, *, follow_symlinks=True) # 仅拷贝文件权限(mode bits),文件内容、属组、属组均不变,参数是两个文件名;follow_symlinks是Python 3.3新增的参数 shutil.copymode(src, dst, *, follow_symlinks=True) # 仅拷贝文件状态信息(包括文件权限,但不包含属主和属组):mode bits, atime, mtime, flags,参数是两个文件名;follow_symlinks是Python 3.3新增的参数 shutil.copystat(src, dst, *, follow_symlinks=True) # 拷贝文件内容和权限,并返回新创建的文件路径;相当于copyfile + copymode,参数是两个路径字符串,且dst可以是一个目录的路径;follow_symlinks是Python 3.3新增的参数 shutil.copy(src, dst, *, follow_symlinks=True) # 与copy函数功能一致,只是会把所有的文件元数据都复制;相当于copyfile + copystat,也相当于 'cp -p'(不包括属主和属组);follow_symlinks是Python 3.3新增的参数 shutil.copy2(src, dst, *, follow_symlinks=True) # 这个工厂方法接收一个或多个通配符字符串,然后创建一个可以被传递给copytree()方法的'ignore'参数的函数。文件名与指定的通配符匹配时,则不会被赋值。 shutil.ignore_patterns(*patterns) # (递归)拷贝整个src目录到目标目录dst,且目标目录dst必须是不存在的。该函数相当于 'cp -pr';目录的权限和时间通过shutilcopystat()来拷贝,单个文件通过shutil.copy2()来考虑诶 shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) # 递归删除,相当于 rm -r shutil.rmtree(path, ignore_errors=False, onerror=None) # 递归移动并返回目标路径,相当于move命令;如果dst是一个已经存在的目录,则src将会被移动到该目录里面;如果dst已经存在,但不是目录,他将会被覆盖;copy_function是Python 3.5新加的关键字参数 shutil.move(src, dst, copy_function=copy2) # 以一个命名tuple的形式返回磁盘使用信息(total, used, free),单位为字节;Python 3.3新增方法 shutil.disk_usage(path) # 更改指定路径的属主和属组,user可以是一个系统用户名或一个uid,group也是这样;这两个参数至少要提供一个;Python 3.3新增方法 shutil.chown(path, user=None, group=None) # 返回命名cmd的文件路径,相当于which命令;Python 3.3新增方法 shutil.which(cmd, mode=os.F_OK|os.X_OK, path=None) 2. 归档操作shutil模块的当当操作是创建和读取压缩文件的高级工具,同时提供文档归档功能。这些高级工具的实现是基于zipfile和tarfile模块实现的,其中与make_archive相关的函数是在Python 2.7版本新增的,而与unpack_archive相关的函数是在Python3.2版本新增的。 # 创建一个归档文件(zip或tar)并返回它的名字; # basename是要创建的文件名称,包含路径,但是不包含特定格式的扩展名; # format是归档格式,可取值为'zip', 'tar', 'gztar', 'bztar'和 ‘xztar’ # root_dir表示归档文件的根目录,即在创建归档之前先切换到它指定的目录, # base_dir表示要进行归档的目录,如果没有提供则对root_dir目录下的所有文件进行归档压缩(它可以是绝对路径,也可以是相对于root_dir的相对路径,它将是归档中所有文件和目录的公共前缀) # root_dir和base_dir默认都是当前目录 # dry_run如果值为Ture表示不会创建归档,但是操作输出会被记录到logger中,可用于测试 # loggger必须是一个兼容PEP 282的对象,通常是logging.Logger的一个实例 # verbose该参数没有用处且已经被废弃 # Python 3.5新增对xztar格式的支持 shutil.make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=0, owner=None, group=None, logger=None) # 解压归档文件 # filename是归档文件的全路径 # extract_dir时解压归档的目标目录名称,如果没有提供,则取当前工作目录 # format是归档格式:'zip', 'tar' 或 'gztar'中的一种。或者是通过register_unpack_format()注册时的其他格式,如果未提供则会根据归档文件的扩展名去查找相应的解压器,如果没找到则会引发ValueError。 shutil.unpack_archive(filename[, extract_dir[, format]]) # 返回支持的归档格式列表,且该列表中的每个元素是一个元组(name, description) # shutil默认提供以下归档格式: # gztar: gzip'ed tar-file # bztar: bzip2'ed tar-file(如果bz2模块可用) # xztar: xz'ed tar-file(如果lzma模块可用) # tar: uncompressed tar file # zip: ZIP file # 我们可以通过register_archive_format()来注册新的归档格式或者为已存在的格式提供我们自己的归档器 shutil.get_archive_formats() # 以列表形式返回所有已注册的解压格式,每个列表中的每个元素都是一个元组(name, extensions, description) # shutil默认提供的解压格式与shutil.get_archive_formats()返回结果一直 # 我们可以通过register_unpack_format()来注册新的格式或为已存在的格式提供我们自己的解压器 shutil.get_unpack_formats() # 注册一个新的归档格式对应的归档器 shutil.register_archive_fromat(name, function[, extra_args[, description]]) # 从支持的归档格式列表中移除指定的归档格式 shutil.unregister_archive_fromat(name) # 注册一个新的解压格式对应的解压器 shutil.register_unpack_format(name, extensions, function[, extra_args[, description]]) # 从支持的解压格式列表中移除指定的挤压格式 shutil.unregister_unpack_format(name) 3. 实例shutil.copyfile('/tmp/myprog/hello.py', '/tmp/hello.py') # 仅复制文件内容 # -rw-r--r-- 1 root root 46 Feb 21 16:22 /tmp/hello.py shutil.copymode('/tmp/myprog/hello.py', '/tmp/hello.py') # 仅复制文件权限位 # -rwxr-xr-x 1 root root 46 Feb 21 16:46 /tmp/hello.py shutil.copystat('/tmp/myprog/hello.py', '/tmp/hello.py') # 仅复制文件元数据(atime, mtime) # -rwxr-xr-x 1 root root 46 Feb 18 17:32 /tmp/hello.py shutil.copy('/tmp/myprog/hello.py', '/tmp/hello1.py') # 复制文件内容和权限位 # -rwxr-xr-x 1 root root 46 Feb 21 16:54 /tmp/hello1.py shutil.copy2('/tmp/myprog/hello.py', '/tmp/hello2.py') # 同时赋值文件内容、权限为和时间 # -rwxr-xr-x 1 root root 46 Feb 18 17:32 /tmp/hello2.py shutil.copytree('/tmp/myprog', '/tmp/myprog1') # 复制一个目录(包括子目录和文件) shutil.move('/tmp/myprog1', '/tmp/myprog2') # 移动文件或目录,也可以看做是“重命名” shutil.rmtree('/tmp/myprog2') # 删除一个目录(包括子目录和文件) shutil.make_archive('/data/myprog', 'gztar', root_dir='/tmp/', base_dir='myprog') # 切换到/tmp目录下,将myprog目录以gzip的格式进行归档压缩,压缩文件路径为/data/myprog.tar.gz 六、其他相关模块(tempfile和fileinput模块)tempfile模块用于创建和操作临时文件;fileinput模块用于同时读取多个文件的内容(包括sys.stdin)。这两个模块比较简单,大家自己翻下官方文档就可以了。 七、总结
更多Python之文件与目录操作及压缩模块(os、zipfile、tarfile、shutil)相关文章请关注PHP中文网! |