Python中文件的读写在程序运行过程中是一个非常重要的操作,我们通常会将一些大量的临时数据暂时存放到一个临时文件,这就需要用到文件的读取与写入功能。话不多说,我们直接上才艺。
讲文件读写前,先说说文件中的数据组织形式,具体可以把文件分成文本文件和二进制文件两大类。
文本文件一般存储普通“字符”文本,在python中默认为unicode字符集(两个字节表示一个字符,最多可以表示65536个),可以使用记事本程序打开。
二进制文件把数据内容用“字节”进行存储,无法用记事本打开。可以用Notepad++软件打开。
文件操作相关模块
模块名称 |
说明 |
io |
文件流的输入和输出操作input output |
os |
基本操作系统功能,包括文件操作 |
glob |
查找符合特定规则的文件路径名 |
fnmatch |
使用模式来匹配文件路径名 |
fileinput |
处理多个输入文件 |
filecmp |
用于文件的比较 |
cvs |
用于csv文件的处理 |
pickle和cPickle |
用于序列化和反序列化 |
xml |
用于xml数据处理 |
bz2, gzip,zipfile,zlib,tarfilc |
用于处理压缩和解压缩文件 |
Python中用open()方法来打开一个文件,并返回文件对象,在对文件进行处理过程中如果文件无法不存在的话,会抛出FileNotFoundError的错误
这里需要注意一点:用open()方法打开文件后,不使用了一定要保证关闭文件对象,即调用close()方法,不然文件对象会一直存在,要是文件很大的话你的内存会占爆。
open()方法的完整语法格式如下
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
其中:
file: 必需,文件路径(相对或绝对)
mode: 可选,文件打开模式,默认为“读取”模式
buffering:设置缓冲
encoding:编码格式,一般为utf-8
errors:报错级别
newline:区分换行符
closefd:传入file的参数类型
opener:设置自定义开启器,开启器的返回值必需是一个打开的文件描述符
简化版格式如下
open(file, mode='r')
默认为文本模式,如果要以二进制模式打开,加上 b 。
模式 |
描述 |
t |
文本模式 |
x |
写模式,新建一个文件,如果该文件已存在则会报错 |
b |
二进制模式 |
+ |
打开一个文件进行更新 |
U |
通用换行模式 |
r |
以只读方式打开文件。文件的指针将会放在文件的开头。(默认模式) |
rb |
以二进制格式打开一个文件用于只读。文件的指针将会放在文件的开头。 |
r+ |
打开一个文件用于读写。文件的指针将会放在文件的开头。 |
rb+ |
以二进制格式打开一个文件用于读写。文件的指针将会放在文件的开头。 |
w |
打开一个文件只用于写入。如果该文件已存在则打开文件,并从头开始编辑,即原来的内容会被删除。如果该文件不存在,则创建新文件。 |
wb |
以二进制格式打开一个文件用于写入。如果该文件已存在则打开文件,并从头开始编辑,即原来的内容会被删除。如果该文件不存在,则创建新文件。 |
w+ |
打开一个文件用于读写,如果该文件已存在则打开文件,并从头开始编辑,即原来的内容会被删除。如果该文件不存在,则创建新文件。 |
wb+ |
以二进制格式打开一个文件用于读写,如果该文件已存在则打开文件,并从头开始编辑,即原来的内容会被删除。如果该文件不存在,则创建新文件。 |
a |
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是,新的内容会被写入到已有内容的之后。如果该文件不存在,则创建新文件写入。 |
ab |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是,新的内容会被写入到已有内容的之后。如果该文件不存在,则创建新文件写入。 |
a+ |
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。也就是,新的内容会被写入到已有内容的之后。如果该文件不存在,则创建新文件写入。 |
ab+ |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是,新的内容会被写入到已有内容的之后。如果该文件不存在,则创建新文件写入。 |
对文件对象进行操作的常用函数如下
方法 |
描述 |
file.close() |
关闭文件,关闭后文件不能再进行读写操作 |
file.flush() |
刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件,而不是被动的等到输出缓冲区写入 |
file.fileno() |
返回一个整型的文件描述符,可以用在如os模块的read方法等一些底层操作上 |
file.isatty() |
如果文件连接到一个终端设备返回True,否则返回false |
file.next() |
返回文件下一行 |
file.read([size]) |
从文件读取指定的字节数,如果未给定或为负则读取所有 |
file.readline([size]) |
读取整行,包括‘\n’字符 |
file.readlines([sizeint]) |
读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行,实际读取值可能比sizeint较大,因为需要填充缓冲区 |
file.seek(offset) |
设置文件当前指针位置 |
file.tell() |
返回文件当前指针位置 |
file.truncate([size]) |
截取文件,截取的字节通过size指定,默认为当前文件指针位置 |
file.write([size]) |
将字符串写入文件,没有返回值。 |
file.writelines(sequence) |
向文件写入一个序列字符串列表,如果需要换行则需要自己加入换行符 |
如果文件打开成功,接下来,调用 read()方法可以一次读取文件的全部内容,Python 把内容读到内存。调用 close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。
file = open('test.txt', 'r')
text = file.read()
print(text)
file.close()
这里一定要记住在最后要关闭文件,不要文件会一直占用你的内容。但是遇到打开文件后,需要写的程序太长的话,这种方法很容易到最后忘记写file.close()去关闭文件,所以,Python引入了with语句来自动调用close()方法关闭文件。
with open('test.txt', 'r') as file:
print(file.read())
从上面的操作方法以及实际运用中我们可以知道file.read()方法如果不给定参数,是默认读取文件中的全部内容,那么如果文件有10G,那你的内存会直接爆炸,所有当你需要导入的文件内容很多时,可以传入size参数,反复调用read(size)方法来获取文件内容。其中size为整数,表示从文件指针的位置开始读取size个字节。
这里多说一句什么是指针
在读取文件中的指针就是代表从文件的哪个位置开始读取文件,每次读取到哪个位置,指针就在哪个位置,只要你不关闭文件,那么下次你读取文件时,就会从上次读取完的位置继续读取文件内容,直到文件内容读取完毕。
with open('test.txt', 'r') as file:
print(file.read(5))
print(file.read(1))
print(file.read(6))
print(file.read(2))
readline()方法是读取文件的一行内容,包括'\n';readlines()方法是读取文件中所有行内容,并返回一个列表。
with open('test_line.txt', 'r') as file:
print(file.readline()) # ABCDEFGHIJKLMNOPQRSTUVWXYZ 换行符
print(file.readlines()) # ['123456789\n', 'hello python\n', 'I love Python']
当你上次读取了几个字节后就关闭了文件,然后下次想继续读取文件内容,并从上次读取的结尾开始读取时,就可以使用seek()方法来指定指针位置。
with open('test_line.txt', 'r') as f:
f.seek(3) # 上次读取到第三个字节的位置
print(f.read(4)) # DEFG
用于显示目前指针的位置
with open('test_line.txt', 'r') as f:
print(f.read(4)) # DEFG
f.tell() #4
truncate()方法用于截取指针之后的内容,所以使用这个方法,文件的打开的模式必须是可写入,不然要报错。
with open('test_line.txt', 'r+') as f:
f.seek(10) # 指定指针位置
f.truncate()
print(f.read())
写文件和读文件是一样的,唯一区别是调用 open()函数时,传入的文件模式是'w'或者'wb',表示写文本文件或写二进制文件。向文件写入内容使用 write(string)方法,该方法返回写入文件的字节数。
with open('test_new.txt', 'w') as f:
f.write('123456')
如果使用f.open()写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用 f.close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用 close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,使用 with语句比较好。
writelines 方法需要通过参数指定一个字符串类型的列表,该方法会将列表中的每一个元素值写入文件。换行需要自己在每一行最后加入换行符 \n。
注意,并没有 writeline 方法,写一行文本需要直接使用 write() 方法。
list1 = ['java\n', 'c\n', 'c++\n', 'python\n', 'javascript\n']
with open('writelines_test.txt', 'w+') as f:
f.writelines(list1)
f.seek(0)
list2 = f.readlines()
for l in list2:
print(l.strip())