Python文件处理(IO 技术)

文章目录

  • Python文件处理
    • 一、文本文件和二进制文件
        • 1. 文本文件
        • 2. 二进制文件
    • 二、文件操作相关模块概述
    • 三、创建文件对象 open()
    • 四、文本文件的写入
        • 1. 基本的文件写入操作
        • 2. 常用编码介绍
        • 3. 中文乱码问题
        • 4. close()关闭文件流
        • 5. 文本文件的读取
        • 6. 二进制文件的读取和写入
    • 五、文件对象的常用属性和方法
        • 文件对象的属性
        • 文件对象的打开模式
        • 文件对象的常用方法
    • 六、文件任意位置操作
    • 七、CSV 文件的操作
        • 1. csv.reader 对象和 csv 文件读取
        • csv.writer 对象和 csv 文件写入
  • pickle 序列化
  • os 和 os.path 模块
        • os 模块-调用操作系统命令
        • os.startfile:直接调用可执行文件
        • os 模块-文件和目录操作
        • os.path 模块
        • walk()递归遍历所有文件和目录
  • shutil 模块(拷贝和压缩)
  • 递归算法

Python文件处理

一、文本文件和二进制文件

按文件中数据组织形式,我们把文件分为文本文件和二进制文件两大类。

1. 文本文件

文本文件存储的是普通“字符”文本,python 默认为 unicode 字符集(两个字节表示
一个字符,最多可以表示:65536 个),可以使用记事本程序打开。注意:像 word 软件编辑的文档不是文本文件。

2. 二进制文件

二进制文件把数据内容用“字节”进行存储,无法用记事本打开。必须使用专用的软件
解码。常见的有:MP4 视频文件、MP3 音频文件、JPG 图片、doc 文档等等。

二、文件操作相关模块概述

在 Python 中,有几个常用的文件操作相关模块可以帮助你进行文件的创建、读取、写入、复制、移动等操作。
Python文件处理(IO 技术)_第1张图片
这些模块为 Python 中文件操作提供了强大的功能和灵活性,可以根据需求选择合适的模块来进行文件处理操作。

三、创建文件对象 open()

open() 函数用于打开一个文件,并返回一个文件对象,可以对该文件对象进行读取写入等操作。
语法格式如下:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

其中:

  • file: 要打开的文件的路径。
  • mode: 打开文件的模式,常用的模式包括:
    ‘r’: 以只读方式打开文件(默认)。
    ‘w’: 以写入方式打开文件,会覆盖已存在的文件。
    ‘a’: 以追加模式打开文件,如果文件存在,数据将被写入到文件末尾。
    ‘b’: 以二进制模式打开文件。
    ‘t’: 以文本模式打开文件(默认)。
  • buffering: 缓冲策略,0 表示不缓冲,1 表示行缓冲,大于 1 表示缓冲区大小。
  • encoding: 文件编码(例如 ‘utf-8’),只适用于文本模式。
  • errors: 指定编解码错误时的处理方式。
  • newline: 控制换行模式。
  • closefd: 是否关闭底层文件描述符。
  • opener: 用于打开文件的自定义函数。

如果只是文件名,代表在当前目录下的文件。文件名可以录入全路径,比如:D:\a\b.txt。
为了减少“\”的输入,可以使用原始字符串:r“d:\b.txt”。
【示例】

f = open(r"d:\b.txt","w")

打开方式有如下几种:
Python文件处理(IO 技术)_第2张图片

文本文件对象和二进制文件对象的创建
如果我们没有增加模式“b”,则默认创建的是文本文件对象,处理的基本单元是“字符”。如果是二进制模式“b”,则创建的是二进制文件对象,处理的基本单元是“字节”。

四、文本文件的写入

1. 基本的文件写入操作

文本文件的写入一般就是三个步骤:

  1. 创建文件对象
  2. 写入数据
  3. 关闭文件对象

【示例】 文本写入操作简单测试

f = open(r'文件对象.txt', 'a')
s = 'hello world!'
f.write(s)
f.close()

执行结果:
Python文件处理(IO 技术)_第3张图片

2. 常用编码介绍

(1). ASCII码
全称为 American Standard Code for Information Interchange,美国信
息交换标准代码,这是世界上最早最通用的单字节编码系统,主要用来显示现代英语及其他西欧语言。
ASCII 码用 7 位表示,只能表示 128 个字符。只定义了 2
7=128 个字符,用7bit 即可完全编码,而一字节 8bit 的容量是 256,所以一字节 ASCII 的编码最高位总是 0。
0~31 表示控制字符如回车、退格、删除等;32~126 表示打印字符即可以
通过键盘输入并且能显示出来的字符;其中 48~57 为 0 到 9 十个阿拉伯数字,65~90 为 26 个大写英文字母,97~122 号为 26 个小写英文字母,其余为一些标点符号、运算符号等,具体可以参考 ASCII 标准表。
Python文件处理(IO 技术)_第4张图片

(2). Unicode
Unicode是一种字符集,它定义了全球范围内几乎所有的字符,并为每个字符分配了一个唯一的码点(code point)。Unicode中的码点用十六进制表示,例如U+0041表示拉丁字母"A"。
Unicode的目标是为世界上每个字符提供一个唯一的标识,并且不受特定的编码限制。这样就能够实现不同语言、不同文化背景的字符在计算机系统中的互通和共享。
Unicode采用不同的编码方式来表示这些码点,常见的编码方式有UTF-8、UTF-16和UTF-32等。其中,UTF-8是最常用的编码方式之一,它使用可变长度的方式来表示字符,能够兼容ASCII码,并且对于常用的字符使用较少的字节表示,提高了存储效率。

(3). UTF-8
UTF-8(Unicode Transformation Format-8)是一种可变长度的编码方式,能够表示Unicode字符集中的任意字符。它是互联网上最常用的字符编码之一,也是现代编程语言中的标准字符编码方式。
UTF-8采用1到4个字节来表示一个字符,具体长度根据字符的不同而变化。对于ASCII码的字符,UTF-8使用1个字节来表示,因此在存储英文文本时,UTF-8和ASCII码是兼容的。而对于非ASCII字符,UTF-8使用不同长度的字节序列来表示,确保了所有Unicode字符都能够被表示。

特点

  • 可变长度:UTF-8使用不定长编码,对于不同的字符使用不同长度的字节来表示。这样可以节省存储空间,并且方便了Unicode字符在不同系统之间的传输和处理。
  • 兼容ASCII码:对于ASCII码的字符,UTF-8使用1个字节来表示。这使得ASCII文本可以直接在UTF-8系统中使用,而不需要进行转换。
  • 自我同步性:UTF-8编码方式具有自我同步性,即任何一个字节都可以作为起始字节。这样能够确保在传输和处理过程中不会出现数据混乱和解码错误。
  • 国际化支持:UTF-8能够支持全球范围内几乎所有的字符,包括中文、日文、韩文等亚洲语言,以及西方语言和其他一些少数民族语言。

(4). GBK
GBK编码是一种中文字符集编码方式,它是中国国家标准GB 2312的扩展形式。GBK编码能够表示中文字符以及包括繁体字在内的一些其他字符。

GBK编码使用双字节表示一个字符,每个字节使用8位二进制数表示。第一个字节的范围是0x81-0xFE,第二个字节的范围是0x40-0xFE(不包括0x7F),因此GBK编码总共可以表示(94+33)×(94+33)=30,664个字符。

GBK编码兼容ASCII码,即对于ASCII字符,使用单字节表示,与标准的ASCII编码一致。而对于中文字符和其他非ASCII字符,使用双字节表示。

注意: GBK编码是一种中文字符集编码方式,不同于Unicode编码。Unicode是一个统一的全球字符集,而GBK编码只是其中的一种特定编码方式,主要用于中文字符的表示

3. 中文乱码问题

windows 操作系统默认的编码是 GBK,Linux 操作系统默认的编码是 UTF-8。当我们用 open()时,调用的是操作系统打开的文件,默认的编码是GBK。

【示例】 中文字符文件,乱码出现测试

f = open(r'中文乱码.txt', 'w')
s = '你好!\n'
f.write(s)  # 把字符串 s 写入到文件中
f.close()

运行结果(Linux 环境中不存在这个问题):
Python文件处理(IO 技术)_第5张图片
**【示例】**通过指定文件编码解决中文乱码问题

f = open(r'中文乱码.txt', 'w', encoding='utf-8')
s = '你好!\n'
f.write(s)  # 把字符串 s 写入到文件中
f.close()

运行结果:
Python文件处理(IO 技术)_第6张图片

4. close()关闭文件流

由于文件底层是由操作系统控制,所以我们打开的文件对象必须显式调用 close()方法关闭文件对象。当调用 close()方法时,首先会把缓冲区数据写入文件(也可以直接调用 flush()方法),再关闭文件,释放文件对象。

为了确保打开的文件对象正常关闭,一般结合异常机制的 finally 或者 with 关键字实现无论何种情况都能关闭打开的文件对象。

【示例】 结合异常机制 finally 确保关闭文件对象

# 结合异常机制 finally 确保关闭文件对象
try:
    f = open('close关闭流.txt', 'w')
    str1 = 'hello'
    f.write(str1)
except BaseException as e:
    print(e)
finally:
    f.close()

运行结果:
Python文件处理(IO 技术)_第7张图片

5. 文本文件的读取

文件的读取一般使用如下三个方法:

  • read([size]):从文件中读取 size 个字符,并作为结果返回。如果没有 size 参数,则读取整个文件。读取到文件末尾,会返回空字符串。
  • readline():读取一行内容作为结果返回。读取到文件末尾,会返回空字符串。
  • readlines():文本文件中,每一行作为一个字符串存入列表中,返回该列表

【示例】 读取一个文件前 3 个字符

with open('with语句(上下文管理器).txt', 'r', encoding='utf-8') as f:
    str1 = f.read(3)
    print(str1)

运行结果:
Python文件处理(IO 技术)_第8张图片

【示例】 文件较小,一次将文件内容读入到程序中

# 文件较小,一次将文件内容读入到程序中
with open('with语句(上下文管理器).txt', 'r', encoding='utf-8') as f:
    str1 = f.read()
    print(str1)

运行结果:
Python文件处理(IO 技术)_第9张图片

【示例】 为文本文件每一行的末尾增加行号

with open('中文乱码.txt', 'r', encoding='utf-8') as f:
    lines = f.readlines()
    lines = [line.rstrip() + '  # ' + str(index + 1) + '\n' for index, line in enumerate(lines)]

with open('文本文件每一行的末尾增加行号.txt', 'w', encoding='utf-8') as f:
    f.writelines(lines)

运行结果:
Python文件处理(IO 技术)_第10张图片

6. 二进制文件的读取和写入

二进制文件的处理流程和文本文件流程一致。首先还是要创建文件对象,不过,我们需要指定二进制模式,从而创建出二进制文件对象。
Python文件处理(IO 技术)_第11张图片
创建好二进制文件对象后,仍然可以使用 write()、read()实现文件的读写操作。
【示例】 读取图片文件,实现文件的拷贝

# 二进制文件的读取
with open('aa.gif', 'rb') as f:
    line = f.read()

# 二进制文件的写入
with open('copy_aa.gif', 'wb') as f:
    f.write(line)

运行结果:

五、文件对象的常用属性和方法

文件对象的属性
属性 说明
name 返回文件的名字
mode 返回文件的打开模式
closed 若文件被关闭则返回 True
文件对象的打开模式

Python文件处理(IO 技术)_第12张图片

文件对象的常用方法

Python文件处理(IO 技术)_第13张图片

六、文件任意位置操作

【示例】 seek()移动文件指针示例

with open('中文乱码.txt', 'r', encoding='utf-8') as f:
    print('文件名:{0}'.format(f.name))
    print(f.tell())
    print('读取的内容:{0}'.format(str(f.readline())))
    print(f.tell())
    f.seek(0, 0)
    print('读取的内容:{0}'.format(str(f.readline())))

运行结果:
Python文件处理(IO 技术)_第14张图片

七、CSV 文件的操作

csv(Comma Separated Values)是逗号分隔符文本格式,常用于数据交换、Excel文件和数据库数据的导入和导出。
与 Excel 文件不同,CSV 文件中:

  • 值没有类型,所有值都是字符串
  • 不能指定字体颜色等样式
  • 不能指定单元格的宽高,不能合并单元格
  • 没有多个工作表
  • 不能嵌入图像图表

Python 标准库的模块 csv 提供了读取和写入 csv 格式文件的对象。

1. csv.reader 对象和 csv 文件读取

【示例】 csv.reader 对象于从 csv 文件读取数据

import csv
with open('豆瓣.csv', 'r', encoding='utf-8') as f:
    read = csv.reader(f)
    for row in read:
        print(row)

运行结果:
Python文件处理(IO 技术)_第15张图片

csv.writer 对象和 csv 文件写入

【示例】 csv.writer 对象写一个 csv 文件

import csv
headers = ['标题', '类型', '评分', '引言']
rows = [('当幸福来敲门', '剧情 传记 家庭', 9.2, '平民励志片。'),
        ('寻梦环游记', '喜剧 动画 奇幻 音乐', 9.1, '死亡不是真的逝去,遗忘才是永恒的消亡。'),
        ('末代皇帝', '剧情 传记 历史', 9.3, '“不要跟我比惨,我比你更惨”再适合这部电影不过了。')]
with open('豆瓣.csv', 'w', encoding='utf-8', newline='') as f:
    write = csv.writer(f)
    write.writerow(headers)
    write.writerows(rows)

运行结果:
Python文件处理(IO 技术)_第16张图片

pickle 序列化

Python 中,一切皆对象,对象本质上就是一个“存储数据的内存块”。有时候,我们需要将“内存块的数据”保存到硬盘上,或者通过网络传输到其他的计算机上。这时候,就需要“对象的序列化和反序列化”。 对象的序列化机制广泛的应用在分布式、并行系统上。
序列化指的是:将对象转化成“串行化”数据形式,存储到硬盘或通过网络传输到其他地方。反序列化是指相反的过程,将读取到的“串行化数据”转化成对象。
Python文件处理(IO 技术)_第17张图片
【示例】 将对象序列化到文件中

import pickle

with open(r"data.dat", "wb") as f:
    a1 = ['ZX', [123], {'age': 18}]
    pickle.dump(a1, f)

【示例】 将获得的数据反序列化成对象

import pickle

with open('data.dat', 'rb') as f:
    a = pickle.load(f)
print(a)

运行结果:
Python文件处理(IO 技术)_第18张图片

os 和 os.path 模块

os 模块可以帮助我们直接对操作系统进行操作。我们可以直接调用操作系统的可执行文件、命令,直接操作文件、目录等等。在系统运维的核心基础。

os 模块-调用操作系统命令

os.system 可以帮助我们直接调用系统的命令
【示例】 os.system 调用 windows 系统的记事本程序

import os
os.system('cmd')
os.system('regedit')

【示例】 os.system 调用 windows 系统中 ping 命令

import os
os.system("ping www.baidu.com")

运行结果:
Python文件处理(IO 技术)_第19张图片

os.startfile:直接调用可执行文件

【示例】 运行安装好的微信

import os
os.startfile('D:\软件\微信\WeChat\WeChat.exe')

运行结果:
Python文件处理(IO 技术)_第20张图片

os 模块-文件和目录操作

os 模块下常用操作文件的方法
Python文件处理(IO 技术)_第21张图片
os 模块下关于目录操作的相关方法
Python文件处理(IO 技术)_第22张图片
【示例】 os 模块:创建、删除目录、获取文件信息等

import os
# 获取文件和文件夹相关的信息
print(os.name)  # windows->nt; linux 和 unix->posix
print(os.sep)  # windows->\; linux 和 unix->/
print(repr(os.linesep))  # windows->\r\n;linux-->\n\
print(os.stat('os模块-文件和目录操作.py'))

# 关于工作目录的操作
print(os.getcwd())  # 返回当前工作目录
# os.chdir('d:')  # 改变当前的工作目录为:d:盘根目录

# 创建目录、创建多级目录、删除
os.mkdir('电影')  # 创建目录
os.makedirs('音乐/周杰伦/稻香')  # 创建多级目录
os.makedirs('../电影1')  # ../表示上一级

print(os.listdir('电影'))
os.path 模块

os.path 模块提供了目录相关(路径判断、路径切分、路径连接、文件夹遍历)的操作。

方法 描述
isabs(path) 判断 path 是否绝对路径
isdir(path) 判断 path 是否为目录
isfile(path) 判断 path 是否为文件
exists(path) 判断指定路径的文件是否存在
getsize(filename) 返回文件的大小
abspath(path) 返回绝对路径
dirname§ 返回目录的路径
getatime(filename) 返回文件的最后访问时间
getmtime(filename) 返回文件的最后修改时间
walk(top,func,arg) 递归方式遍历目录
join(path,*paths) 连接多个 path
split(path) 对路径进行分割,以列表形式返回
splitext(path) 从路径中分割文件的扩展名

【示例】 测试 os.path 中常用方法

import os.path
# 是否为绝对路径
print(os.path.isabs('d:/a1.txt'))
# 是否为目录
print(os.path.isdir('d:/a1.txt'))
# 是否为文件
print(os.path.isfile('d:/a1.txt'))
# 文件是否存在
print(os.path.exists('d:/a1.txt'))
# 文件大小
print(os.path.getsize('d:/a1.txt'))
# 输出所在目录
print(os.path.dirname('d:/a1.txt'))
# 返回创建时间
print(os.path.getctime('d:/a1.txt'))
# 返回最后访问时间
print(os.path.getatime('d:/a1.txt'))
# 返回最后修改时间
print(os.path.getmtime('d:/a1.txt'))
# 输出绝对路径
print(os.path.abspath('d:/a1.txt'))
# 返回元组:目录、文件
print(os.path.split('d:/a1.txt'))
# 返回元组:路径、扩展名
print(os.path.splitext('d:/a1.txt'))
# 路径连接
print(os.path.join('d: ', 'python', 'a.txt'))

运行结果:
Python文件处理(IO 技术)_第23张图片
【示例】 列出指定目录下所有的.py 文件,并输出文件名

# 方法一
import os.path
path = os.getcwd()
file_list = os.listdir(path)
for filename in file_list:
    if filename.endswith('py'):
        print(filename)

# 方法二
import os.path
path = os.getcwd()
file_list = os.listdir(path)
filename = [filename for filename in file_list if filename.endswith('py')]
for f in filename:
    print(f)

Python文件处理(IO 技术)_第24张图片

walk()递归遍历所有文件和目录

os.walk()方法:
返回一个 3 个元素的元组,(dirpath, dirnames, filenames),

  • dirpath:要列出指定目录的路径
  • dirnames:目录下的所有文件夹
  • filenames:目录下的所有文件

【示例】 使用 walk()递归遍历所有文件和目录

import os

all_files = []
path = os.getcwd()
list_files = os.walk(path)
for dirpath, dirnames, filenames in list_files:
    for dir in dirnames:
        all_files.append(os.path.join(dirpath, dir))
    for name in filenames:
        all_files.append(os.path.join(dirpath, name))
# 打印子目录和子文件
for file in all_files:
    print(file)

运行结果:
Python文件处理(IO 技术)_第25张图片

shutil 模块(拷贝和压缩)

shutil 模块是 python 标准库中提供的,主要用来做文件和文件夹的拷贝、移动、删除等;还可以做文件和文件夹的压缩、解压缩操作。
os 模块提供了对目录或文件的一般操作。shutil 模块作为补充,提供了移动、复制、压缩、解压等操作,这些 os 模块都没有提供。

【示例】 实现文件的拷贝

import shutil
# copy 文件内容
shutil.copy('1.txt', '1_copy.txt')

【示例】 实现递归的拷贝文件夹内容(使用 shutil 模块)

import shutil
#"音乐"文件夹不存在才能用。
shutil.copytree("电影/学习","音乐",ignore=shutil.ignore_patterns("*.html","*.htm"))

Python文件处理(IO 技术)_第26张图片
【示例】 实现将文件夹所有内容压缩

import shutil
# 将"电影/学习"文件夹下所有内容压缩到"音乐 2"文件夹下生成 movie.zip
# shutil.make_archive("音乐 2/movie", "zip", "电影/学习")


# 压缩:将指定的多个文件压缩到一个 zip 文件
import zipfile
z = zipfile.ZipFile("a.zip","w")
z.write("1.txt")
z.write("2.txt")
z.close()

运行结果:
在这里插入图片描述
【示例】 实现将压缩包解压缩到指定文件夹

import zipfile
# 解压缩:
z2 = zipfile.ZipFile("a.zip", "r")
z2.extractall("d:/")  # 设置解压的地址
z2.close()

运行结果:
在这里插入图片描述

递归算法

递归是一种常见的解决问题的方法,即把问题逐渐简单化。递归的基本思想就是“自己调用自己”,一个使用递归技术的方法将会直接或者间接的调用自己。
利用递归可以用简单的程序来解决一些复杂的问题。比如:斐波那契数列的计算、汉诺塔、快排等问题。

递归结构包括两个部分

  • 定义递归头。
  • 递归体。

【示例】 使用递归求 n!

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n - 1)

a = factorial(5)
print(a)

运行结果:
Python文件处理(IO 技术)_第27张图片
Python文件处理(IO 技术)_第28张图片
Python文件处理(IO 技术)_第29张图片
【示例】 使用递归算法遍历目录下所有文件

import os
allfile = []

def getFiles(path, level):
    childFiles = os.listdir(path)
    for file in childFiles:
        filepath = os.path.join(path, file)
        if os.path.isdir(filepath):
            getFiles(filepath, level + 1)
        allfile.append("\t" * level + filepath)

getFiles(os.getcwd(), 0)
for f in reversed(allfile):
    print(f)

运行结果:
Python文件处理(IO 技术)_第30张图片

你可能感兴趣的:(python,开发语言)