IO编程
读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
open函数
该函数用于文件处理,传入文件路径和标示符。打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。
打开文件的模式有:
- r ,只读模式【默认,不存在则报错】】
- w,只写模式【不可读;不存在则创建;存在则清空内容;】
- x, 只写模式【不可读;不存在则创建,存在则报错】
- a, 追加模式【可读; 不存在则创建;存在则只追加内容;】
“+” 表示可以同时读写某个文件:
- r+, 读写【可读,可写】
- w+,写读【可读,可写】
- x+ ,写读【可读,可写】
- a+, 写读【可读,可写】
“b”表示以字节的方式操作:
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型
只读模式
只读,文本文件
f = open("writeFile.txt", "r")
data = f.read()
f.close()
print(data)
read()
方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str对象表示。close()
方法关闭文件,文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。
调用read()
会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)
方法,每次最多读取size
个字节的内容。另外,调用readline()
可以每次读取一行内容,调用readlines()
一次读取所有内容并按行返回list
。因此,要根据需要决定怎么调用。
如果文件很小,read()
一次性读取最方便;如果不能确定文件大小,反复调用read(size)
比较保险;如果是配置文件,调用readlines()
最方便。
只读,二进制文件
f = open("writeFile.txt", "rb")
data = f.read()
f.close()
print(data)
//结果
b'\xe5\x8e\x89\xe5\xae\xb3\xe5\x93\x88\xe5\x93\x88\xe5\x8e\...
要读取二进制文件,可以用二进制方式打开,读到的内容是十六进制表示的字节。
要读取非UTF-8
编码的文本文件,需要给open()
函数传入encoding
参数,例如,读取GBK编码的文件:
f = open("writeFile.txt", "r",encoding='gbk')
遇到有些编码不规范的文件,你可能会遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open()
函数还接收一个errors
参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略:
f = open("writeFile.txt", "r",encoding='gbk',errors='ignore')
只写模式
先清空数据,再写
f2 = open("writeFile.txt", "w")
追加数据,只写
f2 = open("writeFile.txt", "a")
f2.write("sdfsdfsfsfs")
f2.close()
//二进制方式打开
先清空数据,再写
f2 = open("writeFile.txt", "wb")
追加数据,只写
f2 = open("writeFile.txt", "ab")
f2.write(bytes("中国", encoding="utf-8"))
f2.close()
你可以反复调用write()
来写入文件,但是务必要调用f.close()
来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()
方法时,操作系统才保证把没有写入的数据全部写入磁盘。
读写模式
r+模式的读写:
# 读写,如果有中文,默认会变成gbk编码
# r+ ,末尾追加,指定在最后
f = open("writeFile.txt", "r+", encoding='utf-8')
data = f.read()
# 读或写完数据之后,指定会在最后的位置,指针位置以字节算,tell用来获取指针位置,seek用来改变指定位置
print(f.tell())
f.write("厉害")
print(f.tell())
data = f.read()
print(f.tell())
f.write("哈哈")
print(f.tell())
f.close()
print(data)
//结果,120,126,126,132
w+模式的读写:
# 写读,如果有中文,默认会变成gbk编码
# w+ ,先清空,在写之后,才可以读
f = open("writeFile.txt", "w+", encoding='utf-8')
#此时内容已清空,所以读到的内容为空,指针为0
data = f.read()
# 读或写完数据之后,指定会在最后的位置,指针位置以字节算,tell用来获取指针位置,seek用来改变指定位置
print(f.tell())
f.write("厉害")
print(f.tell())
data = f.read()
print(f.tell())
f.write("哈哈")
print(f.tell())
//结果,0,6,6,12
a+模式的读写:
# 追加,如果有中文,默认会变成gbk编码
# a+ ,打开文件时就将指针移到最后的位置
f = open("writeFile.txt", "a+", encoding='utf-8')
data = f.read()
# 读或写完数据之后,指定会在最后的位置,指针位置以字节算,tell用来获取指针位置,seek用来改变指定位置
print(f.tell())
f.write("厉害")
print(f.tell())
data = f.read()
print(f.tell())
f.write("哈哈")
print(f.tell())
# 此时指针是最后,要想读所有数据,把指针放到0位置,再读一次,就有数据了
f.seek(0)
data = f.read()
f.close()
print(data)
//结果,12,18,18,24,厉害哈哈
IO的一些方法
刷新文件内部缓冲区
f.flush()
读取一行数据
f.readline()
一次读取所有内容并按行返回list
f.readlines()
截取当前指针前面的数据,指针后面的数据全部删除
f.truncate()
读取数据,可以指定读取的字节数量
f.read()
注意 ,f是可以遍历的,每个元素是一行数据
for line in f:
print(line)
可以用with 关键字来避免每次都调用close
with open("writeFile.txt", "r", encoding='utf-8') as f:
print(f.readline())
可以同时打开两个文件,下面的例子是复制文件内容到一个新的文件里面
with open("writeFile.txt", "r", encoding='utf-8') as f, open("copyFile.txt", "w", encoding='utf-8') as f2:
for data in f:
f2.write(data)