Python学习笔记015——文件file的常规操作之一(文本文件)

时间:2023-03-09 22:36:43
Python学习笔记015——文件file的常规操作之一(文本文件)

1 什么是文件

文件是用于数据存储的单位

文件通常用来长期保存数据

读写文件是最常见的I/O操作。Python内置了读写文件的函数,用法和C是兼容的。

读写文件的功能都是由操作系统提供的,一般而言,操作系统不允许普通的程序直接操作磁盘,所以读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),再通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个对象(写文件)。

2 文件的打开和关闭的基本规则

文件需要在使用时先打开才能读写

在不需要读写文件后,应及时关闭文件以释放系统资源

任何操作系统对打开的文件数有最大数限制

2.1 文件的打开 open()

f = open('/Users/michael/test.txt', 'r')

/Users/michael/test.txt ——文件路径及文件名

r ——标识符

返回文件流对象,打开失败则会IOError报错!并且给出错误码和详细的信息告诉你文件不存在:

例如在 汉字.txt 文件所在的 文件夹test 位置打开 终端

Python学习笔记015——文件file的常规操作之一(文本文件)

>>> 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中内容

Python学习笔记015——文件file的常规操作之一(文本文件)

>>> 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中内容

Python学习笔记015——文件file的常规操作之一(文本文件)

>>> 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文件内容

Python学习笔记015——文件file的常规操作之一(文本文件)

>>> 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+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

下图很好的总结了这几种模式:

Python学习笔记015——文件file的常规操作之一(文本文件)

模式 r r+ w w+ a a+
+ +   +   +
  + + + + +
创建     + + + +
覆盖     + +    
指针在开始 + + + +    
指针在结尾         + +

参考文件:

廖雪峰 的 文件读写

python模块

python 文件操作总结

浅谈 Python 的 with 语句

示例微代码


input.txt 文件的内容

今天是平安日
明天是圣诞节
我们更期待春节

python读取代码

# 打开文件,返回文件流对象 用f绑定
try:
    f = open("input.txt")

    print("文件打开成功")
    s = f.read(3)  # 读写两个字符
    print(s)  # '今天'

    f.close()
except IOError:
    print("打开文件失败!!")

print("程序结束")

运行

文件打开成功
今天是
程序结束

参考文档:python文件输入和输出