本文以Python3以上为学习基础。
目录
1、 使用文件操作第一原则
2、open函数
2.1、文件打开模式
2.1.1、只读模式打开文件——只读(r)
2.1.2、读写模式打开文件——读写模式(r+)
2.1.3、写模式打开文件——写模式(w)
2.1.4、读写模式打开文件——读写模式(w+)
2.1.5、写模式打开文件(追加内容)——写模式(a)
2.1.6、读写模式打开文件(追加内容)——读写模式(a)
2.2、二进制模式打开文件
3、close()函数
在Linux中所有的东西都存放在文件中。
下面讲解Python中文件的相关知识。
在某个文件夹下面建立了一个文件:zxc.txt。
并且在里面输入了如下内容:
我们现在打开文件,并且遍历文件的内容:
可以看到我们把文件的内容遍历出来了。
但是每行代码的内容什么含义呢?
我们一行一行的看。
第一行:
f = open("C:\\Users\\lenovo\\Desktop\\Python_File_test\\zxc.txt")
第一行就是打开文件,采用的方法是open函数。但是在使用文件操作的时候我们要明确一个原则。
使用open函数一定要同时把文件关闭函数close()写上。
为什么呢?我们做个验证。
这个就是我创建好的文件zxc.txt。
当前的文件内容是空的。
下面我们执行下面的代码。
注意:我只是打开了文件,没有关闭文件。
为了方便查看。加了一个代码执行结束的提示。
下面我们查看zxc.txt文件的内容。
我们成功输出结果:1 2$
我们下面试着手动修改以下文件。
看到没有,我们的文件被占用。但是是什么占用了呢?
我们利用Windows的资源监视器看看。
很明显,python占用这个文件。原因就是我们使用open函数带开了这个文件。没有关闭,这个文件一直被占用。
因此我们在使用open函数的时候一定要close文件。否则你一直开着它,就算你不懂也应该能想到一定有问题。具体情况后续介绍。
我们现在知道要close到文件了,但是怎么做呢?我们试试看。
利用前面的文件句柄 f 进行close。
这时候我们使用Windows的资源监视器看看这个文件的相关进程。
结果很明显。文件相关进程结束了。
所以我们只要写了open函数,一定要紧跟着写上close()函数。然后在open函数和close函数之间进行添加代码处理,就像下面这样。
这里文件关闭函数也就说了,格式就是:文件对象.close(),例如上例中的f.close()。
继续说open函数,open函数是Python的一个内置函数。用于创建一个file对象(文件对象)。
这里文件对象就是等号前面的 f。这样变量f跟对象文件 zxc.txt 用线连起来了(就是对象引用)。
关于对象的引用和放风筝一样。放风筝的转轮就是f,风筝就是zxc.txt,连接转轮和风筝的线就是Python。这里涉及到Python的深浅拷贝问题,具体可以参考:Python深浅拷贝。
我们现来看open函数的语法格式:
file object = open(file_name [, access_mode][, buffering]
在本例中就是zxc.txt的文件路径。
关于这个文件路径的写法,有两种:
(1)open("zxc.txt")
意味着这个文件zxc.txt是在当前文件夹内的。就是你Python程序的所在文件夹。
(2)open("C:\\Users\\lenovo\\Desktop\\Python_File_test\\zxc.txt")
这就是打开其它文件夹内的文件,用相对路径或者绝对路径来表示,从而让python能够找到那个文件。里面的 \ 用了 \\ 表示,是为了防止转义。
可以省略,默认的打开模式是只读(r)。本例中就是只读打开。
其他的文件打开模式参考下表:(表格来源于:菜鸟教程)
模式 | 描述 |
---|---|
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
U | 通用换行模式(不推荐)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
文件打开模式有很多,我们总结一下主要用到的是下面几种。
模式 | 可做操作 | 若文件不存在 | 是否覆盖文件原来内容 |
r | 只读 | 报错 | —— |
r+ | 可读、可写 | 报错 | 是 |
w | 只写 | 创建 | 是 |
w+ | 可读、可写 | 创建 |
是 |
a | 只写 | 创建 | 否,追加写 |
a+ | 可读、可写 | 创建 | 否,追加写 |
下面我们用例子来看,怎么写。(下面所有的例子,为了方便查看,我把文件创建在和Python程序所在的文件夹里面,这样可以直接写文件名称)
文件存在的场合:
这里我尝试文件中写 hello world。报错意思没有写权限。
文件不存在的场合:
很明显,出现了文件不存在的错误。
文件存在的场合,zxc.txt文件的内容:
下面我们用读写模式打开文件,并向里面写入hello world。
这时候文件内容,注意看:光标在h前面。原来的内容被删除。
文件不存在的场合:
很明显,出现了文件不存在的错误。
文件存在的场合,zxc.txt的文件内容:
下面我们用写模式打开文件,并向里面写入Python。
文件的内容如下,仔细看:输入的光标位置在最开始。P前面有个光标。
很明显,删除原来的文件内容,重新写入Python,并且把光标放在文件最开始。
文件不存在的场合:
可以看到我的文件夹里面没有zxc.txt。
下面我们用写模式打开文件,并向里面写入Python。
这时候我的文件夹:
可以看到,自己创建了zxc.txt文件。
文件内容如下,仔细看:输入的光标位置在最开始。P前面有个光标。
很明显,自己创建了文件,写入Python,并且把光标放在文件最开始。
既然w是写模式,我们试着读取文件内容看看。这时候的文件内容是Python。
很明显,出现文件不能读的错误。
文件存在的场合,文件内容:
既然是读写模式(w+),所以我们先读文件内容,再写入Python,然后再读取文件内容。
可以看到我们打印文件内容的时候没有报错,但是没有打印出任何内容?
那我们写入成功了吗?
很明显写入成功了,但是为什么没有打印出来内容?
其实是由于读写机制的问题,当一个文件被读或者写一次后,文件中文件指针指向的是整个文件的末尾,再次读时从末尾开始读的话肯定是什么都到。
文件不存在的场合:可以看到我的文件夹里面没有zxc.txt。
这时候我们验证读写模式(w+)。
可以看到创建了文件zxc.txt。
其实文件写模式(w)、读写模式(w+)还可以用作删除文件内容。
因为他们整个工作原理就是把文件原来的内容删除,然后写入新的内容。
如果我们写入的内容为空,那么不就是删除文件内容。
就如同下面这个例子。
文件内容:
可以看到,文件zxc.txt里面有无数个Python。
下面我们利用读写模式,但是不写入任何内容。
这时候我们查看文件内容:
文件内容是空,原来的内容删掉了。
同理,写模式(w)是一样的。
文件存在的场合,文件内容如下:
下面我们写入内容 hello world
文件内容:
可以看到,Python后面追加了hello world。
文件不存在的场合,可以看到,我的文件夹里没有文件zxc.txt:
下面我们连续写入内容 hello world 和 Python。
可以看到zxc.txt被创建
文件内容:
既然是写模式,我们验证一下zxc.txt不能读。
出现错误不能读。
文件存在的场合,文件内容如下:
下面我们写入内容 hello world
文件内容:
可以看到,Python后面追加了hello world。
文件不存在的场合,可以看到,我的文件夹里没有文件zxc.txt:
下面我们连续写入内容 hello world 和 Python。
可以看到zxc.txt被创建
文件内容:
既然是读写模式,我们验证一下zxc.txt可读。
没有出现错误,但是没有打印出内容。
原因其实是由于读写机制的问题,当一个文件被读或者写一次后,文件中文件指针指向的是整个文件的末尾,再次读时从末尾开始读的话肯定是什么都到。
所有模式我们都进行了说明,我们再看一下回顾一下我们整理的文件打开模式表:
模式 | 可做操作 | 若文件不存在 | 是否覆盖文件原来内容 |
r | 只读 | 报错 | —— |
r+ | 可读、可写 | 报错 | 是 |
w | 只写 | 创建 | 是 |
w+ | 可读、可写 | 创建 |
是 |
a | 只写 | 创建 | 否,追加写 |
a+ | 可读、可写 | 创建 | 否,追加写 |
对于第三个参数buffering。
buffering的可取值有0,1, >1三个
这个参数我没用到过,所以这里我无法进行举例解释了,所以如果需要,还请自行查询。
我们看到了在文件打开模式中有以下模式:rb、wb……有这种带 b 的。
什么意思呢?
就是用二进制的方式打开文件。
有什么用?
我们来验证一下:
创建文件zxc.txt,内容如下:
下面读取文件:
很明显,我们出现了以下错误:
UnicodeDecodeError: 'gbk' codec can't decode byte 0x82 in position 0: incomplete multibyte sequence
主要原因是因为编码的问题,可能是因为0x82这个字节在gbk编码中没有这个字符,可能原字符是两个字节,在gbk里被解析成了一个字节,导致字符不存在。
解决方法有两个:一个是二进制读取,一个是改编编码方式。
二进制读取就是利用rb、wb……
这就是我们文件打开方式有二进制的原因。
下面我们进行验证。
可以看到,二进制就把文件内容读出来了。并且看到原来是中文的句号在gbk里面没有。
前面的r、w、r+……就是上面讲的读模式、写模式、读写模式等等。配合二进制方式,就可以读取文件了。
上面文件打开模式例子都有close函数的用法:f.close()。