python 文件操作

By | 2019年1月14日

                                            强大自己是唯一获得幸福的途径,这是长远的,而非当下的玩乐!


操作流程

>>> 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

file.close()

关闭文件。关闭后文件不能再进行读写操作。

2

file.flush()

刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。

3

file.fileno()

返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。

4

file.isatty()

如果文件连接到一个终端设备返回 True,否则返回 False。

5

file.read([size])

从文件读取指定的字节数,如果未给定或为负则读取所有。

6

file.readline([size])

读取整行,包括 "\n" 字符。

7

file.readlines([sizeint])

读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。

8

file.seek(offset[, whence])

设置文件当前位置

9

file.tell()

返回文件当前位置。

10

file.truncate([size])

从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 Widnows 系统下的换行代表2个字符大小。

11

file.write(str)

将字符串写入文件,返回的是写入的字符长度。

12

file.writelines(sequence)

向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。

示例 

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将光标移动到开头,可以读取数据

 

请关注公众号获取更多资料

发表评论