1 什么是文件
文件是用于数据存储的单位
文件通常用来长期保存数据
读写文件是最常见的I/O操作。Python内置了读写文件的函数,用法和C是兼容的。
读写文件的功能都是由操作系统提供的,一般而言,操作系统不允许普通的程序直接操作磁盘,所以读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),再通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个对象(写文件)。
2 文件的打开和关闭的基本规则
文件需要在使用时先打开才能读写
在不需要读写文件后,应及时关闭文件以释放系统资源
任何操作系统对打开的文件数有最大数限制
2.1 文件的打开 open()
f = open('/Users/michael/test.txt', 'r')
/Users/michael/test.txt ——文件路径及文件名
r ——标识符
返回文件流对象,打开失败则会IOError报错!并且给出错误码和详细的信息告诉你文件不存在:
例如在 汉字.txt 文件所在的 文件夹test 位置打开 终端
>>> f = open('汉字.txt',"r") >>> f <_io.TextIOWrapper name='汉字.txt' mode='r' encoding='UTF-8'>
打开test_son.txt文件方式
>>> f2 = open("./test/test.txt","r") >>> f2 <_io.TextIOWrapper name='./test/test.txt' mode='r' encoding='UTF-8'>
注意绝对目录 /Users/michael/test.txt 和相对目录 ./test/test.txt 打开方式区别。
当打开失败时,会提示报错FileNotFoundError
>>> f2 = open("/test/test.txt","r") Traceback (most recent call last): File "<stdin>", line 1, in <module> FileNotFoundError: [Errno 2] No such file or directory: '/test/test.txt'
打开文件出现错误时,可以用try...except进行异常处理
# 打开文件tset.txt,返回文件流对象并用f绑定 try: f = open("test.txt") print("文件打开成功") # 此处应进行读写操作 # ..... #关闭文件 f.close() except IOError: print("打开文件失败!!") print("程序结束")
2.2 读文件
2.2.1 read()方法
read() 方法用于从文件读取指定的字节数,如果未给定或为负则读取所有内容至内存中。
语法: fileObject.read([size]) fileObject 表示文件流对象,size 表示从文件中最多读取的字节数,可选的,若无参数size,则读取至文件结束为止(它范围为字符串对象)。返回从字符串中读取的字节。
>>> f = open("汉字.txt","r") >>> f.read() '开始学习Python课程了\n'
备注:汉字.txt文件中语句为:开始学习Python课程了。
2.2.2 readline()方法
该方法时每次读取文件中的一行内容,返回一个字符串对象;
优点是读取时占用内存小,比较适合较大的文件,
文件readline.txt中内容
>>> f = open('readline.txt','r') >>> f.readline() '今天是1月26日,\n' >>> f.readline() '晴,外面可以看到阳光\n' >>> f.readline() '我在认真地学习python\n' >>> f.readline() '\n' >>> f.readline() '' >>> f.readline()
注意到在输出时自动在末尾加上换行符,readline()方法读到换行符\n时,就会挂起,当再调用时,指针就会向下移动,那如果人为地加上换行符,会是什么样的效果。
文件readline.txt中内容
>>> f2 = open('readline.txt','r') >>> f2.readline() '今天是1月26日,\n' >>> f2.readline() '晴,外面\\n可以看到阳光\n' >>> f2 = open('readline.txt','r') >>> f2.readline() '今天是1月26日,\n' >>> f2.readline() '晴,外面\\n可以看到阳光\n' >>> f2.readline() '晴,外面\\\\n可以看到阳光\n' >>> f2.readline() "晴,外面'\\\\n'可以看到阳光\n" >>> f2.readline() '我在认真地学习python\n'
2.2.3 readlines() 方法
readlines()方法是读取整个文件,并返回一个列表对象,每行作为一个列表元素;故读取大文件时会占有较大的内存
readlines.txt文件内容
>>> f = open('readlines.txt','r') >>> f.readlines() ['我是第一行\n', '我是第二行\n', '我是第三行\n']
2.2.4 read() readline() readlines() 使用对比
如果文件很小,read()
一次性读取最方便;如果不能确定文件大小,反复调用read(size)
比较保险;如果是配置文件,调用readlines()
最方便:
>>> f = open('readlines.txt','r') >>> for line in f: ... line.strip() # 把末尾的'\n'删掉 ... '我是第一行' '我是第二行' '我是第三行' >>> f1 = open('readlines.txt','r') >>> for line in f1.readlines(): ... line.strip() # 把末尾的'\n'删掉 ... '我是第一行' '我是第二行' '我是第三行'
2.3 关闭文件close()
第一,降低系统资源消耗;第二,系统再同一时间内打开的文件数量是有限的;故操作完文件后调用close()方法将文件关闭,
语法: f.close() f 为文件流对象
但是文件读写时都由可能产生IOError,一旦出现错误,位于后面的f.close()就不会被调用,也即打开的文件不能被关闭,这个会造成系统资源浪费,为了不管文件是否出错均能正确地关闭该文件,我们可以使用 try...finally 来实现对文件的关闭
try: f = open('test.txt', 'r') f.read() finally: if f: f.close()
2.4 with方法
with方法从 Python 2.5 开始引入的一种与异常处理相关的功能,非常适用与资源访问处理场合;
无论操作对象在使用过程中是否发生异常,在最后阶段,with方法均能将其“清理”并释放资源。
有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。
例如文件使用后的关闭,线程中锁的自动获取和释放等
使用with方法可以替代 try...finally 对文件处理功能
将“2.3 关闭文件close()”中的代码用with语句优化
with open("test.txt",'r') as f: f.read()
冗余的代码被with语句优化后显得更加优雅。
2.4 文件的常用方法
方法名 | 说明 |
---|---|
F代表文件流对象 | |
F.close() | 关闭文件 |
F.readline() | 读取一行数据,如果到达文件尾则返回空字符串 |
F.readlines(max_char=-1) | 返回每行字符串列表, max_char为最大字符数 |
F.read(size=-1) | 从一个文件流中最多读取size个字符(或字节(仅二进制)) |
F.writelines(lines) | 字符串列表的内容写到文件中 |
F.write(text) | 写一个字符串(或字节)到文件流中,返回写入字符数(或字节数) |
F.tell() | 返回当前文件流的绝对位置 |
F.seek(offset, whence=0) | 改变数据流的位置,返回新的绝对位置 |
F.readable() | 判断文件是否可读,可读返回True,否则返回Flase |
F.writeable() | 判断文件是否可写。可写返回True,否则返回False |
F.flush() | 把写入文件对象的缓存内容写入到磁盘 |
2.5 mode模式字符的含义
字符 | 含义 |
---|---|
'r' | 以只读方式打开(默认) |
'w' | 以只写方式打开,删除原有文件内容(如果文件不存在,则尝试创建该文件并以只写方式打开) |
'x' | 创建一个新文件,并以写模式打开这个文件,如果文件存在则会产生FileExistError错误 |
'a' | 以只写方式打开一个文件,如果有原文件,则追加到文件末尾 |
't' | 文本文件模式打开(默认) |
'b' | 用二进制模式打开 |
'+' | 为更新内容打开一个磁盘文件(可读可写) |
备注:当模式为"a"时,不管是否通过seek定位,均直接在文件尾追加文件
缺省模式是 'rt'
可以组合使用:
'w+b' 可以实现二进制随机读写,当打开文件时,文件内容将被清空
'r+' 以文本模式读和更新模式打开文件,打开文件时不会清空文件内容
示例:
f = open("output.txt", 'w') f.write("开始向文件中写入数据...\r\n") count = f.write("数据的第二行\r\n") print("您已写入", count, "个字符") L = ["数据的第三行\r\n", "数据的第四行\r\n", "数据的第五行"] f.writelines(L) f.close()
此时文件 output.txt 文件中出现:
开始向文件中写入数据... 数据的第二行 数据的第三行 数据的第四行 数据的第五行
以该文件为基础,再次进行文件操作
f = open("output.txt", 'r+') s = f.read(1) print("第一个字符是:", s) f.write("坏") f.write("\r\n坏") f.close()
运行
开始向文件中写入数据... 数据的第二行 数据的第三行 数据的第四行 数据的第五行坏 坏
附不同模式打开的完全列表:
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
下图很好的总结了这几种模式:
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
参考文件:
示例微代码
input.txt 文件的内容
今天是平安日 明天是圣诞节 我们更期待春节
python读取代码
# 打开文件,返回文件流对象 用f绑定 try: f = open("input.txt") print("文件打开成功") s = f.read(3) # 读写两个字符 print(s) # '今天' f.close() except IOError: print("打开文件失败!!") print("程序结束")
运行
文件打开成功 今天是 程序结束
参考文档:python文件输入和输出