重大消息!重大消息!(Python机甲合体!!!文件超兽武装~)Python文件操作大全,看这篇就够了(二)

上一篇:重大消息!重大消息!(Python机甲合体!!!文件超兽武装~)Python文件操作大全,看这篇就够了(一)

 

遍历目录和处理文件

一个常见的编程任务是遍历目录树并处理目录树中的文件。让我们来探讨一下如何使用内置的Python函数 os.walk() 来实现这一功能。os.walk() 用于通过从上到下或从下到上遍历树来生成目录树中的文件名。处于本节的目的,我们想操作以下的目录树:

├── folder_1
│   ├── file1.py
│   ├── file2.py
│   └── file3.py
├── folder_2
│   ├── file4.py
│   ├── file5.py
│   └── file6.py
├── test1.txt
└── test2.txt
复制代码

以下是一个示例,演示如何使用 os.walk() 列出目录树中的所有文件和目录。

os.walk() 默认是从上到下遍历目录:

import os
for dirpath, dirname, files in os.walk('.'):
   print(f'Found directory: {dirpath}')
   for file_name in files:
       print(file_name)
复制代码

os.walk() 在每个循环中返回三个值:

  1. 当前文件夹的名称
  2. 当前文件夹中子文件夹的列表
  3. 当前文件夹中文件的列表

在每次迭代中,会打印出它找到的子目录和文件的名称:

Found directory: .
test1.txt
test2.txt
Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py
复制代码

免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流

要以自下而上的方式遍历目录树,则将 topdown=False 关键字参数传递给 os.walk()

for dirpath, dirnames, files in os.walk('.', topdown=False):
    print(f'Found directory: {dirpath}')
    for file_name in files:
        print(file_name)
复制代码

传递 topdown=False 参数将使 os.walk() 首先打印出它在子目录中找到的文件:

Found directory: ./folder_1
file1.py
file3.py
file2.py
Found directory: ./folder_2
file4.py
file5.py
file6.py
Found directory: .
test1.txt
test2.txt
复制代码

如你看见的,程序在列出根目录的内容之前列出子目录的内容。 这在在你想要递归删除文件和目录的情况下非常有用。 你将在以下部分中学习如何执行此操作。 默认情况下,os.walk 不会访问通过软连接创建的目录。 可以通过使用 followlinks = True 参数来覆盖默认行为。


创建临时文件和目录

Python提供了 tempfile 模块来便捷的创建临时文件和目录。

tempfile 可以在你程序运行时打开并存储临时的数据在文件或目录中。 tempfile 会在你程序停止运行后删除这些临时文件。

现在,让我们看看如何创建一个临时文件:

from tempfile import  TemporaryFile

# 创建一个临时文件并为其写入一些数据
fp = TemporaryFile('w+t')
fp.write('Hello World!')
# 回到开始,从文件中读取数据
fp.seek(0)
data = fp.read()
print(data)
# 关闭文件,之后他将会被删除
fp.close()
复制代码

免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流

第一步是从 tempfile 模块导入 TemporaryFile 。 接下来,使用 TemporaryFile() 方法并传入一个你想打开这个文件的模式来创建一个类似于对象的文件。这将创建并打开一个可用作临时存储区域的文件。

在上面的示例中,模式为 w + t,这使得 tempfile 在写入模式下创建临时文本文件。 没有必要为临时文件提供文件名,因为在脚本运行完毕后它将被销毁。

写入文件后,您可以从中读取并在完成处理后将其关闭。 一旦文件关闭后,将从文件系统中删除。 如果需要命名使用 tempfile 生成的临时文件,请使用 tempfile.NamedTemporaryFile()

使用 tempfile 创建的临时文件和目录存储在用于存储临时文件的特殊系统目录中。 Python将在目录列表搜索用户可以在其中创建文件的目录。

在Windows上,目录按顺序为 C:\TEMPC:\TMP\TEMP\TMP。 在所有其他平台上,目录按顺序为 / tmp/var/tmp/usr/tmp 。 如果上述目录中都没有,tempfile 将在当前目录中存储临时文件和目录。

.TemporaryFile() 也是一个上下文管理器,因此它可以与with语句一起使用。 使用上下文管理器会在读取文件后自动关闭和删除文件:

with TemporaryFile('w+t') as fp:
    fp.write('Hello universe!')
    fp.seek(0)
    fp.read()
# 临时文件现在已经被关闭和删除
复制代码

这将创建一个临时文件并从中读取数据。 一旦读取文件的内容,就会关闭临时文件并从文件系统中删除。

tempfile 也可用于创建临时目录。 让我们看一下如何使用 tempfile.TemporaryDirectory()来做到这一点:

import tempfile
import os

tmp = ''
with tempfile.TemporaryDirectory() as tmpdir:
    print('Created temporary directory ', tmpdir)
    tmp = tmpdir
    print(os.path.exists(tmpdir))

print(tmp)
print(os.path.exists(tmp))
复制代码

调用 tempfile.TemporaryDirectory() 会在文件系统中创建一个临时目录,并返回一个表示该目录的对象。 在上面的示例中,使用上下文管理器创建目录,目录的名称存储在 tmpdir 变量中。 第三行打印出临时目录的名称,os.path.exists(tmpdir) 来确认目录是否实际在文件系统中创建。

在上下文管理器退出上下文后,临时目录将被删除,并且对 os.path.exists(tmpdir)的调用将返回False,这意味着该目录已成功删除。


删除文件和目录

您可以使用 osshutilpathlib 模块中的方法删除单个文件,目录和整个目录树。 以下将介绍如何删除你不再需要的文件和目录。

Python中删除文件

要删除单个文件,请使用 pathlib.Path.unlink()os.remove()os.unlink()

os.remove()os.unlink() 在语义上是相同的。 要使用 os.remove()删除文件,请执行以下操作:

import os

data_file = 'C:\\Users\\vuyisile\\Desktop\\Test\\data.txt'
os.remove(data_file)
复制代码

使用 os.unlink() 删除文件与使用 os.remove() 的方式类似:

import os

data_file = 'C:\\Users\\vuyisile\\Desktop\\Test\\data.txt'
os.unlink(data_file)
复制代码

在文件上调用 .unlink().remove() 会从文件系统中删除该文件。 如果传递给它们的路径指向目录而不是文件,这两个函数将抛出 OSError 。 为避免这种情况,可以检查你要删除的内容是否是文件,并在确认是文件时执行删除操作,或者可以使用异常处理来处理 OSError

import os

data_file = 'home/data.txt'
# 如果类型是文件则进行删除
if os.path.is_file(data_file):
    os.remove(data_file)
else:
    print(f'Error: {data_file} not a valid filename')
复制代码

os.path.is_file() 检查 data_file 是否实际上是一个文件。 如果是,则通过调用 os.remove() 删除它。 如果 data_file 指向文件夹,则会向控制台输出错误消息。

以下示例说明如何在删除文件时使用异常处理来处理错误:

import os

data_file = 'home/data.txt'
# 使用异常处理
try:
    os.remove(data_file)
except OSError as e:
    print(f'Error: {data_file} : {e.strerror}')
复制代码

上面的代码尝试在检查其类型之前先删除该文件。 如果 data_file 实际上不是文件,则抛出的 OSError 将在except子句中处理,并向控制台输出错误消息。 打印出的错误消息使用 Python f-strings格式化。

最后,你还可以使用 pathlib.Path.unlink() 删除文件:

from pathlib import Path

data_file = Path('home/data.txt')
try:
    data_file.unlink()
except IsADirectoryError as e:
    print(f'Error: {data_file} : {e.strerror}')
复制代码

这将创建一个名为 data_filePath 对象,该对象指向一个文件。 在 data_file 上调用.unlink()将删除 home / data.txt 。 如果 data_file 指向目录,则引发 IsADirectoryError 。 值得注意的是,上面的Python程序和运行它的用户具有相同的权限。 如果用户没有删除文件的权限,则会引发 PermissionError

删除目录

免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流

标准库提供了一下函数来删除目录:

  • os.rmdir()
  • pathlib.Path.rmdir()
  • shutil.rmtree()

要删除单个目录或文件夹可以使用 os.rmdir()pathlib.Path.rmdir() 。这两个函数只在你删除空目录的时候有效。如果目录不为空,则会抛出 OSError 。下面演示如何删除一个文件夹:

import os

trash_dir = 'my_documents/bad_dir'

try:
    os.rmdir(trash_dir)
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')
复制代码

现在,trash_dir 已经通过 os.rmdir() 被删除了。如果目录不为空,则会在屏幕上打印错误信息:

Traceback (most recent call last):
  File '', line 1, in 
OSError: [Errno 39] Directory not empty: 'my_documents/bad_dir'
复制代码

同样,你也可使用 pathlib 来删除目录:

from pathlib import Path

trash_dir = Path('my_documents/bad_dir')

try:
    trash_dir.rmdir()
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')
复制代码

这里创建了一个 Path 对象指向要被删除的目录。如果目录为空,调用 Path 对象的 .rmdir() 方法删除它。

删除完整的目录树

要删除非空目录和完整的目录树,Python提供了 shutil.rmtree() :

import shutil

trash_dir = 'my_documents/bad_dir'

try:
    shutil.rmtree(trash_dir)
except OSError as e:
    print(f'Error: {trash_dir} : {e.strerror}')
复制代码

当调用 shutil.rmtree() 时,trash_dir 中的所有内容都将被删除。 在某些情况下,你可能希望以递归方式删除空文件夹。 你可以使用上面讨论的方法之一结合 os.walk() 来完成此操作:

import os

for dirpath, dirnames, files in os.walk('.', topdown=False):
    try:
        os.rmdir(dirpath)
    except OSError as ex:
        pass
复制代码

这将遍历目录树并尝试删除它找到的每个目录。 如果目录不为空,则引发OSError并跳过该目录。 下表列出了本节中涉及的功能:

函数 描述
os.remove() 删除单个文件,不能删除目录
os.unlink() 和os.remove()一样,职能删除单个文件
pathlib.Path.unlink() 删除单个文件,不能删除目录
os.rmdir() 删除一个空目录
pathlib.Path.rmdir() 删除一个空目录
shutil.rmtree() 删除完整的目录树,可用于删除非空目录

复制、移动和重命名文件和目录

Python附带了 shutil 模块。 shutil 是shell实用程序的缩写。 它为文件提供了许多高级操作,来支持文件和目录的复制,归档和删除。 在本节中,你将学习如何移动和复制文件和目录。

复制文件

shutil 提供了一些复制文件的函数。 最常用的函数是 shutil.copy()shutil.copy2() 。 使用shutil.copy() 将文件从一个位置复制到另一个位置,请执行以下操作:

import shutil

src = 'path/to/file.txt'
dst = 'path/to/dest_dir'
shutil.copy(src, dst)
复制代码

shutil.copy() 与基于UNIX的系统中的 cp 命令相当。 shutil.copy(src,dst) 会将文件 src 复制到 dst 中指定的位置。 如果 dst 是文件,则该文件的内容将替换为 src 的内容。 如果 dst 是目录,则 src 将被复制到该目录中。 shutil.copy() 仅复制文件的内容和文件的权限。 其他元数据(如文件的创建和修改时间)不会保留。

要在复制时保留所有文件元数据,请使用 shutil.copy2()

import shutil

src = 'path/to/file.txt'
dst = 'path/to/dest_dir'
shutil.copy2(src, dst)
复制代码

使用 .copy2() 保留有关文件的详细信息,例如上次访问时间,权限位,上次修改时间和标志。

复制目录

虽然 shutil.copy() 只复制单个文件,但 shutil.copytree() 将复制整个目录及其中包含的所有内容。 shutil.copytree(src,dest) 接收两个参数:源目录和将文件和文件夹复制到的目标目录。

以下是如何将一个文件夹的内容复制到其他位置的示例:

import shutil
dst = shutil.copytree('data_1', 'data1_backup')
print(dst)  # data1_backup
复制代码

在此示例中,.copytree()data_1 的内容复制到新位置 data1_backup 并返回目标目录。 目标目录不能是已存在的。 它将被创建而不带有其父目录。 shutil.copytree() 是备份文件的一个好方法。

移动文件和目录

要将文件或目录移动到其他位置,请使用 shutil.move(src,dst)

src 是要移动的文件或目录,dst 是目标:

import shutil
dst = shutil.move('dir_1/', 'backup/')
print(dst)  # 'backup'
复制代码

如果 backup/ 存在,则 shutil.move('dir_1/','backup/')dir_1/ 移动到 backup/ 。 如果 backup/ 不存在,则 dir_1/ 将重命名为 backup

重命名文件和目录

Python包含用于重命名文件和目录的 os.rename(src,dst)

import os
os.rename('first.zip', 'first_01.zip')
复制代码

上面的行将 first.zip 重命名为 first_01.zip 。 如果目标路径指向目录,则会抛出 OSError

重命名文件或目录的另一种方法是使用 pathlib 模块中的 rename()

from pathlib import Path
data_file = Path('data_01.txt')
data_file.rename('data.txt')
复制代码

要使用 pathlib 重命名文件,首先要创建一个 pathlib.Path() 对象,该对象包含要替换的文件的路径。 下一步是在路径对象上调用 rename() 并传入你要重命名的文件或目录的新名称。


归档

归档是将多个文件打包成一个文件的便捷方式。 两种最常见的存档类型是ZIP和TAR。 你编写的Python程序可以创建存档文件,读取存档文件和从存档文件中提取数据。 你将在本节中学习如何读取和写入两种压缩格式。

读取ZIP文件

zipfile 模块是一个底层模块,是Python标准库的一部分。 zipfile 具有可以轻松打开和提取ZIP文件的函数。 要读取ZIP文件的内容,首先要做的是创建一个 ZipFile 对象。ZipFile 对象类似于使用 open() 创建的文件对象。ZipFile 也是一个上下文管理器,因此支持with语句:

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:
    pass
复制代码

免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流

这里创建一个 ZipFile 对象,传入ZIP文件的名称并以读取模式下打开。 打开ZIP文件后,可以通过 zipfile 模块提供的函数访问有关存档文件的信息。 上面示例中的 data.zip 存档是从名为 data 的目录创建的,该目录包含总共5个文件和1个子目录:

.
|
├── sub_dir/
|   ├── bar.py
|   └── foo.py
|
├── file1.py
├── file2.py
└── file3.py
复制代码

要获取存档文件中的文件列表,请在 ZipFile 对象上调用 namelist()

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:
    zipobj.namelist()
复制代码

这会生成一个文件列表:

['file1.py', 'file2.py', 'file3.py', 'sub_dir/', 'sub_dir/bar.py', 'sub_dir/foo.py']
复制代码

.namelist() 返回存档文件中文件和目录的名称列表。要检索有关存档文件中文件的信息,使用 .getinfo()

import zipfile

with zipfile.ZipFile('data.zip', 'r') as zipobj:
    bar_info = zipobj.getinfo('sub_dir/bar.py')
    print(bar_info.file_size)
复制代码

这将输出:

15277
复制代码

.getinfo() 返回一个 ZipInfo 对象,该对象存储有关存档文件的单个成员的信息。 要获取有关存档文件中文件的信息,请将其路径作为参数传递给 .getinfo() 。 使用 getinfo() ,你可以检索有关存档文件成员的信息,例如上次修改文件的日期,压缩大小及其完整文件名。 访问 .file_size 将以字节为单位检索文件的原始大小。

以下示例说明如何在Python REPL中检索有关已归档文件的更多详细信息。 假设已导入 zipfile 模块,bar_info 与在前面的示例中创建的对象相同:

>>> bar_info.date_time
(2018, 10, 7, 23, 30, 10)
>>> bar_info.compress_size
2856
>>> bar_info.filename
'sub_dir/bar.py'
复制代码

bar_info 包含有关 bar.py 的详细信息,例如压缩的大小及其完整路径。

第一行显示了如何检索文件的上次修改日期。 下一行显示了如何在归档后获取文件的大小。 最后一行显示了存档文件中 bar.py 的完整路径。

ZipFile 支持上下文管理器协议,这就是你可以将它与with语句一起使用的原因。 操作完成后会自动关闭 ZipFile 对象。 尝试从已关闭的 ZipFile 对象中打开或提取文件将导致错误。

提取ZIP文件

免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流

zipfile 模块允许你通过 .extract().extractall() 从ZIP文件中提取一个或多个文件。

默认情况下,这些方法将文件提取到当前目录。 它们都采用可选的路径参数,允许指定要将文件提取到的其他指定目录。 如果该目录不存在,则会自动创建该目录。 要从压缩文件中提取文件,请执行以下操作:

>>> import zipfile
>>> import os

>>> os.listdir('.')
['data.zip']

>>> data_zip = zipfile.ZipFile('data.zip', 'r')

>>> # 提取单个文件到当前目录
>>> data_zip.extract('file1.py')
'/home/test/dir1/zip_extract/file1.py'

>>> os.listdir('.')
['file1.py', 'data.zip']

>>> # 提所有文件到指定目录
>>> data_zip.extractall(path='extract_dir/')

>>> os.listdir('.')
['file1.py', 'extract_dir', 'data.zip']

>>> os.listdir('extract_dir')
['file1.py', 'file3.py', 'file2.py', 'sub_dir']

>>> data_zip.close()
复制代码

第三行代码是对 os.listdir() 的调用,它显示当前目录只有一个文件 data.zip

接下来,以读取模式下打开 data.zip 并调用 .extract() 从中提取 file1.py.extract() 返回提取文件的完整文件路径。 由于没有指定路径,.extract() 会将 file1.py 提取到当前目录。

下一行打印一个目录列表,显示当前目录现在包括除原始存档文件之外的存档文件。 之后显示了如何将整个存档提取到指定目录中。.extractall() 创建 extract_dir 并将 data.zip 的内容提取到其中。 最后一行关闭ZIP存档文件。

从加密的文档提取数据

zipfile 支持提取受密码保护的ZIP。 要提取受密码保护的ZIP文件,请将密码作为参数传递给 .extract().extractall() 方法:

>>> import zipfile

>>> with zipfile.ZipFile('secret.zip', 'r') as pwd_zip:
...     # 从加密的文档提取数据
...     pwd_zip.extractall(path='extract_dir', pwd='Quish3@o')
复制代码

将以读取模式打开 secret.zip 存档。 密码提供给 .extractall() ,并且压缩文件内容被提取到 extract_dir 。 由于with语句,在完成提取后,存档文件会自动关闭。

创建新的存档文件

要创建新的ZIP存档,请以写入模式(w)打开 ZipFile 对象并添加要归档的文件:

>>> import zipfile

>>> file_list = ['file1.py', 'sub_dir/', 'sub_dir/bar.py', 'sub_dir/foo.py']
>>> with zipfile.ZipFile('new.zip', 'w') as new_zip:
...     for name in file_list:
...         new_zip.write(name)
复制代码

在该示例中,new_zip 以写入模式打开,file_list 中的每个文件都添加到存档文件中。 with语句结束后,将关闭 new_zip 。 以写入模式打开ZIP文件会删除压缩文件的内容并创建新存档文件。

要将文件添加到现有的存档文件,请以追加模式打开 ZipFile 对象,然后添加文件:

>>> with zipfile.ZipFile('new.zip', 'a') as new_zip:
...     new_zip.write('data.txt')
...     new_zip.write('latin.txt')
复制代码

这里打开在上一个示例中以追加模式创建的 new.zip 存档。 在追加模式下打开 ZipFile 对象允许将新文件添加到ZIP文件而不删除其当前内容。 将文件添加到ZIP文件后,with语句将脱离上下文并关闭ZIP文件。

打开TAR存档文件

TAR文件是像ZIP等未压缩的文件存档。 它们可以使用 gzipbzip2lzma 压缩方法进行压缩。 TarFile 类允许读取和写入TAR存档。

下面是从存档中读取:

import tarfile

with tarfile.open('example.tar', 'r') as tar_file:
    print(tar_file.getnames())
复制代码

tarfile 对象像大多数类似文件的对象一样打开。 它们有一个 open() 函数,它采用一种模式来确定文件的打开方式。

使用“r”,“w”或“a”模式分别打开未压缩的TAR文件以进行读取,写入和追加。 要打开压缩的TAR文件,请将模式参数传递给 tarfile.open(),其格式为 filemode [:compression] 。 下表列出了可以打开TAR文件的可能模式:

模式 行为
r 以无压缩的读取模式打开存档
r:gz 以gzip压缩的读取模式打开存档
r:bz2 以bzip2压缩的读取模式打开存档
w 以无压缩的写入模式打开存档
w:gz 以gzip压缩的写入模式打开存档
w:xz 以lzma压缩的写入模式打开存档
a 以无压缩的追加模式打开存档

.open() 默认为'r'模式。 要读取未压缩的TAR文件并检索其中的文件名,请使用 .getnames()

>>> import tarfile

>>> tar = tarfile.open('example.tar', mode='r')
>>> tar.getnames()
['CONTRIBUTING.rst', 'README.md', 'app.py']
复制代码

这以列表的方式返回存档中内容的名字。

注意:为了向你展示如何使用不同的tarfile对象方法,示例中的TAR文件在交互式REPL会话中手动打开和关闭。

通过这种方式与TAR文件交互,你可以查看运行每个命令的输出。 通常,你可能希望使用上下文管理器来打开类似文件的对象。

此外可以使用特殊属性访问存档中每个条目的元数据:

>>> for entry in tar.getmembers():
...     print(entry.name)
...     print(' Modified:', time.ctime(entry.mtime))
...     print(' Size    :', entry.size, 'bytes')
...     print()
CONTRIBUTING.rst
 Modified: Sat Nov  1 09:09:51 2018
 Size    : 402 bytes

README.md
 Modified: Sat Nov  3 07:29:40 2018
 Size    : 5426 bytes

app.py
 Modified: Sat Nov  3 07:29:13 2018
 Size    : 6218 bytes
复制代码

在此示例中,循环遍历 .getmembers() 返回的文件列表,并打印出每个文件的属性。.getmembers() 返回的对象具有可以通过编程方式访问的属性,例如归档中每个文件的名称,大小和上次修改时间。 在读取或写入存档后,必须关闭它以释放系统资源。

从TAR存档中提取文件

在本节中,你将学习如何使用以下方法从TAR存档中提取文件:

  • .extract()
  • .extractfile()
  • .extractall()

要从TAR存档中提取单个文件,请使用 extract() ,传入文件名:

>>> tar.extract('README.md')
>>> os.listdir('.')
['README.md', 'example.tar']
复制代码

README.md 文件从存档中提取到文件系统。 调用 os.listdir() 确认 README.md 文件已成功提取到当前目录中。 要从存档中解压缩或提取所有内容,请使用 .extractall()

>>> tar.extractall(path="extracted/")
复制代码

.extractall() 有一个可选的 path 参数来指定解压缩文件的去向。 这里,存档被提取到 extracted 目录中。 以下命令显示已成功提取存档:

$ ls
example.tar  extracted  README.md

$ tree
.
├── example.tar
├── extracted
|   ├── app.py
|   ├── CONTRIBUTING.rst
|   └── README.md
└── README.md

1 directory, 5 files

$ ls extracted/
app.py  CONTRIBUTING.rst  README.md
复制代码

要提取文件对象以进行读取或写入,请使用 .extractfile() ,它接收 文件名或 TarInfo 对象作为参数。 .extractfile() 返回一个可以读取和使用的类文件对象:

>>> f = tar.extractfile('app.py')
>>> f.read()
>>> tar.close()
复制代码

打开的存档应在读取或写入后始终关闭。 要关闭存档,请在存档文件句柄上调用 .close() ,或在创建 tarfile对象时使用with语句,以便在完成后自动关闭存档。 这将释放系统资源,并将你对存档所做的任何更改写入文件系统。

创建新的TAR存档

创建新的TAR存档,你可以这样操作:

>>> import tarfile

>>> file_list = ['app.py', 'config.py', 'CONTRIBUTORS.md', 'tests.py']
>>> with tarfile.open('packages.tar', mode='w') as tar:
...     for file in file_list:
...         tar.add(file)

>>> # Read the contents of the newly created archive
>>> with tarfile.open('package.tar', mode='r') as t:
...     for member in t.getmembers():
...         print(member.name)
app.py
config.py
CONTRIBUTORS.md
tests.py
复制代码

首先,你要创建要添加到存档的文件列表,这样你就不必手动添加每个文件。

下一行使用with光线文管理器在写入模式下打开名为 packages.tar 的新存档。 以写入模式('w')打开存档使你可以将新文件写入存档。 将删除存档中的所有现有文件,并创建新存档。

创建并填充存档后,with上下文管理器会自动关闭它并将其保存到文件系统。 最后三行打开刚刚创建的存档,并打印出其中包含的文件的名称。

要将新文件添加到现有存档,请以追加模式('a')打开存档:

>>> with tarfile.open('package.tar', mode='a') as tar:
...     tar.add('foo.bar')

>>> with tarfile.open('package.tar', mode='r') as tar:
...     for member in tar.getmembers():
...         print(member.name)
app.py
config.py
CONTRIBUTORS.md
tests.py
foo.bar
复制代码

在追加模式下打开存档允许你向其添加新文件而不删除其中已存在的文件。

使用压缩存档

tarfile 可以读取和写入使用 gzipbzip2lzma 压缩的TAR存档文件。 要读取或写入压缩存档,请使用tarfile.open() ,为压缩类型传递适当的模式。

例如,要读取或写入使用 gzip 压缩的TAR存档的数据,请分别使用 'r:gz''w:gz' 模式:

>>> files = ['app.py', 'config.py', 'tests.py']
>>> with tarfile.open('packages.tar.gz', mode='w:gz') as tar:
...     tar.add('app.py')
...     tar.add('config.py')
...     tar.add('tests.py')

>>> with tarfile.open('packages.tar.gz', mode='r:gz') as t:
...     for member in t.getmembers():
...         print(member.name)
app.py
config.py
tests.py
复制代码

'w:gz' 以写模式模式打开 gzip 压缩的存档,'r:gz' 以读模式打开 gzip 压缩的存档。 无法在追加模式下打开压缩存档。 要将文件添加到压缩存档,你必须创建新存档。


一个更简单的方式创建存档

Python标准库还支持使用 shutil 模块中的高级方法创建TAR和ZIP存档。 shutil 中的归档实用工具允许你创建,读取和提取ZIP和TAR归档。 这些实用工具依赖于较底层的 tarfilezipfile 模块。

使用 shutil.make_archive() 创建存档

shutil.make_archive() 至少接收两个参数:归档的名称和归档格式。

默认情况下,它将当前目录中的所有文件压缩为 format 参数中指定的归档格式。 你可以传入可选的 root_dir 参数来压缩不同目录中的文件。 .make_archive() 支持 ziptarbztargztar 存档格式。

以下是使用 shutil 创建TAR存档的方法:

import shutil

# shutil.make_archive(base_name, format, root_dir)
shutil.make_archive('data/backup', 'tar', 'data/')
复制代码

这将复制 data / 中的所有内容,并在文件系统中创建名为 backup.tar 的存档并返回其名称。 要提取存档,请调用 .unpack_archive()

shutil.unpack_archive('backup.tar', 'extract_dir/')
复制代码

调用 .unpack_archive() 并传入存档名称和目标目录,将 backup.tar 的内容提取到 extract_dir/ 中。 ZIP存档可以以相同的方式创建和提取。


读取多个文件

Python支持通过 fileinput 模块从多个输入流或文件列表中读取数据。 此模块允许你快速轻松地循环遍历一个或多个文本文件的内容。 以下是使用 fileinput 的典型方法:

import fileinput
for line in fileinput.input()
    process(line)
复制代码

fileinput 默认从传递给 sys.argv 的命令行参数获取其输入。

使用 fileinput 循环遍历多个文件

让我们使用 fileinput 构建一个普通的UNIX工具 cat 的原始版本。 cat 工具按顺序读取文件,将它们写入标准输出。 当在命令行参数中给出多个文件时,cat 将连接文本文件并在终端中显示结果:

# File: fileinput-example.py
import fileinput
import sys

files = fileinput.input()
for line in files:
    if fileinput.isfirstline():
        print(f'\n--- Reading {fileinput.filename()} ---')
    print(' -> ' + line, end='')
print()
复制代码

在当前目录中有两个文本文件,运行此命令会产生以下输出:

$ python3 fileinput-example.py bacon.txt cupcake.txt
--- Reading bacon.txt ---
 -> Spicy jalapeno bacon ipsum dolor amet in in aute est qui enim aliquip,
 -> irure cillum drumstick elit.
 -> Doner jowl shank ea exercitation landjaeger incididunt ut porchetta.
 -> Tenderloin bacon aliquip cupidatat chicken chuck quis anim et swine.
 -> Tri-tip doner kevin cillum ham veniam cow hamburger.
 -> Turkey pork loin cupidatat filet mignon capicola brisket cupim ad in.
 -> Ball tip dolor do magna laboris nisi pancetta nostrud doner.

--- Reading cupcake.txt ---
 -> Cupcake ipsum dolor sit amet candy I love cheesecake fruitcake.
 -> Topping muffin cotton candy.
 -> Gummies macaroon jujubes jelly beans marzipan.
复制代码

免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流

fileinput 允许你检索有关每一行的更多信息,例如它是否是第一行(.isfirstline()),行号(.lineno())和文件名(.filename())。


总结

你现在知道如何使用Python对文件和文件组执行最常见的操作。 你已经了解使用不同的内置模块来读取,查找和操作文件。

你现在可以用Python来实现:

  • 获取目录内容和文件属性
  • 创建目录和目录树
  • 使用匹配模式匹配文件名
  • 创建临时文件和目录
  • 移动,重命名,复制和删除文件或目录
  • 从不同类型的存档文件中读取和提取数据
  • 使用 fileinput 同时读取多个文件

你可能感兴趣的:(Python文件操作,软件测试,自动化测试,python,Python文件操作,程序人生,经验分享,软件测试)