强大自己是唯一获得幸福的途径,这是长远的,而非当下的玩乐!
操作流程
>>> f = open("test/aa", encoding="utf-8", mode="r") # 打开文件
>>> for i in f:
... print(i,end="") # 对文件操作
...
line 1 for aa test file
line 2 for aa test file
>>> f.close() # 关闭文件
正如我们平时操作文件是一个样的流程,
第一:我们需要打开一个文件
第二:对文件修改查看或做其他操作
第三:关闭这个文件
首先,为什么我们用for呢?因为如果文件太大,我们不能直接全读出来,这样会把内存撑爆,所以我们应当一行一行读取,还有如果我们中间的操作导致程序崩溃了,报错退出了呢?这样下面的close就不会执行,文件也就不会关闭了,所以我们需要引出打开文件的方式,使用with
>>> with open("test/aa", encoding="utf-8", mode="r") as f: # 打开文件
... for i in f:
... print(i,end="") # 操作
...
line 1 for aa test file
line 2 for aa test file
不管是中间报错退出,亦或者其他原因,使用with,python都会帮我们把文件关闭,并且代码看起来是不是更简洁了呢?
打开方式
针对于encoding,大家对前面的密码本应该有印象,也就是文件用的什么编码,我们就需要用什么编码打开,不然密码本对应不上,显示出来的就是一堆乱码了。
针对mode,也就是打开文件的方式,有以下这些:
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
U | 通用换行模式(不推荐)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。(追加) |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
使用以上的编码方式,以及模式打开文件后,我们就需要操作文件了,有以下方法:
1 | 关闭文件。关闭后文件不能再进行读写操作。 |
2 | 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。 |
3 | 返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 |
4 | 如果文件连接到一个终端设备返回 True,否则返回 False。 |
5 | 从文件读取指定的字节数,如果未给定或为负则读取所有。 |
6 | 读取整行,包括 "\n" 字符。 |
7 | 读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。 |
8 | 设置文件当前位置 |
9 | 返回文件当前位置。 |
10 | 从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 Widnows 系统下的换行代表2个字符大小。 |
11 | 将字符串写入文件,返回的是写入的字符长度。 |
12 | 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。 |
示例
1,按字节读取(seek就是按字节)注:一个中文在utf-8占3个字节,如果seek正好停留在这3个字节中间,会报错
>>> with open("test/aa",encoding="utf-8") as f: # 默认就是以 "r" 的模式打开
... print(f.read(3))
... print(f.tell())
...
lin # 读取3个字节
3 # tell,返回当前光标位置
2,a 与 w 的区别
➜ ~ cat test/aa
line 1 for aa test file
line 2 for aa test file
>>> with open("test/aa", encoding="utf-8", mode="a") as abc:
... abc.write("first add")
...
➜ ~ cat test/aa
line 1 for aa test file
line 2 for aa test file
first add # a 为追加
>>> with open("test/aa", encoding="utf-8", mode="w") as sdd:
... sdd.write("w add")
...
➜ ~ cat test/aa
w add # w 为清空插入
但如果不存在 test/aa 不管是a 抑或是w 都会创建
3 a+ 与 w+
➜ ~ ls test
aa
with open("./test/bb", encoding="utf-8", mode="w+") as wa:
... wa.write("wadd")
... wa.read()
...
'' # w+ 代表写完后可读,但明明写入了 为什么读出来是空呢?
# 因为读取是根据seek光标移动的,当你写入时,光标也跟随移动到最后,read()操作
# 同样是在最后读取,所以什么都没读取到
➜ ~ ls test
aa bb # 原来没有,创建了bb文件
>>> with open("./test/bb", encoding="utf-8", mode="a+") as aa:
... aa.write("aadd")
... aa.seek(0)
... aa.read()
...
'waddaadd' # a为追加,不会清空, 写入后 seek将光标移动到开头,可以读取数据