概述
Python 文件 I/O(输入/输出)是用户程序和系统交互的过程,整个过程的交互性不是那么明显,使用输入机制,允许程序读取外部数据(包括来自磁盘、光盘等存储设备的数据),用户输入数据;使用输出机制,允许程序记录运行状态,将程序数据输出到磁盘、光盘等存储设备中;
Python 提供有非常丰富的文件 I/O 支持,它既提供了 pathlib 和 os.path 来操作各种路径,也提供了全局的 open() 函数来打开文件(在打开文件之后,程序既可读取文件的内容,也可向文件输出内容)。而且 Python 提供了多种方式来读取文件内容,因此非常简单、灵活。此外,在 Python 的 os 模块下也包含了大量进行文件 I/O 的函数,使用这些函数来读取、写入文件也很方便,因此读者可以根据需要选择不同的方式来读写文件。摘录python文件操作(I/O)。
python中文件的操作通常可以分成两类:
1.系统级操作:删除、修改权限,作用于文件本身
2.应用级操作:读、写操作,作用于文件内容
对于文件应用的操作通常有着较为固定的格式,可以归纳如下所示:
1.打开open文件,使用open()函数,返回一个文件对象
2.读写read/write文件,这里主要有读文件有read(),readline(),readlines()函数;而写文件就只有write()函数
3.关闭close文件,完成对文件的读写之后,需要对文件进行关闭,调用close()函数。
1.open()函数
python中对文件的操作是操作“文件对象”,因此需要先调用open()返回一个文件对象
file = open(file_name [, mode[, buffering]])
此格式中,用 [] 括起来的部分,表示作为可选操作,可以使用,也可以省略。其中,各个参数所代表的含义如下:
- file:表示要创建的文件对象。
- mode:可选参数,用于指定文件的打开模式。可选的打开模式如表 1 所示。如果不写,则默认以只读(r)模式打开文件。
- buffing:可选参数,用于指定对文件做读写操作时,是否使用缓冲区(本节后续会详细介绍)。
至于打开模式选择可以参考模式中的列表部分
这里有以文本文件和二进制文件打开文件,那文件文件和二进制文件到底有什么不同呢?
文本文件用于打开如.txt,.c等课件的字符类文件,这些文件使用文本编辑器打开时,可见其内容部分;二进制文件用来保存如音视频等,使用文本编辑器打开为乱码甚至是无法打开的,之所以如此是因为本文件中采用的是 ASCII、UTF-8、GBK 等字符编码,文本编辑器可以识别出这些编码格式,并将编码值转换成字符展示出来。而对于二进制文件,文本编辑器无法识别这些文件的编码格式,只能按照字符编码格式胡乱解析,所以最终看到的是一堆乱码。
使用 open() 函数以文本格式打开文件和以二进制格式打开文件,唯一的区别是对文件中换行符的处理不同。
在 Windows 系统中,文件中用 "\r\n" 作为行末标识符(即换行符),当以文本格式读取文件时,会将 "\r\n" 转换成 "\n";反之,以文本格式将数据写入文件时,会将 "\n" 转换成 "\r\n"。这种隐式转换换行符的行为,对用文本格式打开文本文件是没有问题的,但如果用文本格式打开二进制文件,就有可能改变文本中的数据(将 \r\n 隐式转换为 \n)。
#当前程序文件同目录存在 test.txt 文件
file = open("test.txt")
print(file)
当以默认模式打开文件时,默认使用 r 权限,默认使用GBK由于该权限要求打开的文件必须存在
#默认方式打开文件
f = open("coutry.txt")
#查询当前的编码方式
print(f.encoding)
#查看文件访问模式
print(f.mode)
#查看文件的名称
print(f.name)
2.read()
文件对象提供了read()函数可以按照字节/字符读取文件内容,到底是读取字节还是字符,取决于使用 open() 函数打开文件时,是否使用了 b 模式,如果使用了 b 模式,则每次读取一个字节;反之,则每次读取一个字符。其格式如下:
file.read([size])
其中,file 表示打开的文件对象;size 作为一个可选参数,用于指定要读取的字符个数,如果省略,则默认一次性读取所有内容。
采用循环并指定读取的大小
file = open("test.txt", 'r', True)
while True:
# 每次读取一个字符
ch = file .read(10)
# 如果没有读到数据,跳出循环
if not ch:
break
file .close()
或者是一次性全部读取,这里包括了指定编码格式的情形
# 指定使用二进制方式读取文件内容,test.txt 以 utf-8 编码存储
f = open("test.txt", 'rb', True)
# 直接读取全部文件,并调用bytes的decode将字节内容恢复成字符串
print(f.read().decode('utf-8'))
f.close()
上面程序在调用 open() 函数时,传入了 rb 模式,这表明采用二进制模式读取文件,此时文件对象的 read() 方法返回的是 bytes 对象,程序可调用 bytes 对象的 decode() 方法将它恢复成字符串。由于此时读取的 a.txt 文件是以 UTF-8 的格式保存的,因此程序需要使用 decode() 方法恢复字符串时显式指定使用 UTF-8 字符集。
然而read()方法有个不足之处就在于如果文件过大,则一次性读取全部内容到内存这明显是不合适的,会造成过度消耗内存的情形,因此更推荐使用每次固定读取一定数量的的字符或者字节,故而更加推荐使用逐行读取的形式。
一般情况下,逐行读取只适用于以文本格式打开的文件,道理很简单,只有文本文件才有行的概念,二进制文件没有所谓行的概念。
文件对象提供了 readline() 和 readlines() 两个函数来逐行读取文件,其中 readline() 函数用于读取一行内容,而 readlines() 函数用于读取文件内的所有行。
3.readline()函数
readline() 函数用于读取文件中的一行,包含最后的换行符“\n”。此函数的基本语法格式为:
file.readline([size])
其中,file 为打开的文件对象;size 为可选参数,用于指定读取每一行时,一次最多读取的字符数。
和 read() 函数一样,此函数成功读取文件数据的前提是,使用 open() 函数指定打开文件的模式必须为 r(只读模式)或 r+(读写模式)。
下面程序示范了使用 readline() 方法来读取文件内容:
file = open("coutry.txt","r")
while True:
# 每次读取一行
line = file.readline()
#指定每行读取的长度
#line = file.readline(5)
# 如果没有读到数据,跳出循环
if not line: break
# 输出line
print(line)
file.close()
而coutry.txt的内容工有三行:
python
testdd
studyy
输出结果为:
python
testdd
studyy
由于 readline() 函数在读取文件中一行的内容时,会读取最后的换行符“\n”,再加上 print() 函数输出内容时默认会换行,所以输出结果中会看到多出了一个空行。
4.readlines()
readlines() 函数用于读取文件中的所有行,它和调用不指定 size 参数的 read() 函数类似,只不过该函数返回是一个字符串列表,其中每个元素为文件中的一行内容。
和 readline() 函数一样,readlines() 函数在读取每一行时,会连同行尾的换行符一块读取。
readlines() 函数的基本语法格式如下:
file.readlines()
其中,file 为打开的文件对象。和 read()、readline() 函数一样,它要求打开文件的模式使用 r(只读)或者 r+(读写)。
file = open("coutry.txt","r")
lines = file.readlines()
for line in lines:
print(line)
file.close()
5.write()
Python 中的文件对象提供了 write() 函数,可以向文件中写入指定内容。该函数的语法格式如下:
file.write(string)
其中,file 表示已经打开的文件对象;string 表示要写入文件的字符串(或字节串,仅适用写入二进制文件中)。
注意,在使用 write() 向文件中写入数据,需保证使用 open() 函数是以
r+、w、w+、a 或 a+ 的模式打开文件,否则执行 write() 函数会抛出 io.UnsupportedOperation 错误。
f = open("a.txt", 'w')
f.write("写入一行新数据")
f.close()
前面已经讲过,如果打开文件模式中包含 w(写入),那么向文件中写入内容时,会先清空原文件中的内容,然后再写入新的内容。因此运行上面程序,再次打开 a.txt 文件,只会看到新写入的内容。
而如果打开文件模式中包含 a(追加),则不会清空原有内容,而是将新写入的内容会添加到原内容后边。
f = open("a.txt", 'a')
f.write("\n写入一行新数据")
f.close()
因此,采用不同的文件打开模式,会直接影响 write() 函数向文件中写入数据的效果。
另外,在写入文件完成后,一定要调用 close() 函数将打开的文件关闭,否则写入的内容不会保存到文件中。例如,将上面程序中最后一行 f.close() 删掉,再次运行此程序并打开 a.txt,你会发现该文件是空的。这是因为,当我们在写入文件内容时,操作系统不会立刻把数据写入磁盘,而是先缓存起来,只有调用 close() 函数时,操作系统才会保证把没有写入的数据全部写入磁盘文件中。
除此之外,如果向文件写入数据后,不想马上关闭文件,也可以调用文件对象提供的 flush() 函数,它可以实现将缓冲区的数据写入文件中。例如:
f = open("a.txt", 'w')
f.write("写入一行新数据")
f.flush()