day4
文件操作
对文件的操作分三步:
1、打开文件获取文件的句柄,句柄就理解为这个文件
2、通过文件句柄操作文件
3、关闭文件
打开文件
打开文件有以下几个模式:
模式 | 说明 |
r | 只读模式(默认)。只能读不能写,文件不存在会报错 |
w | 只写模式。【文件不可读;文件不存在则创建;文件存在内容则会删除它的内容】 |
a | 追加模式。【文件不可读; 文件不存在则创建;文件存在内容则只追加内容】 |
r+ | 读写模式。可读、可写;可追加,如果打开的文件不存在的话,会报错 |
w+ | 写读模式。使用w+的话,已经存在的文件内容会被清空,可以读到已经写的文件内容 |
a+ | 追加读写模式。文件不存在则创建;存在则只追加内容 |
rU | "U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用) |
r+U | "U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用) |
rb | "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注) |
wb | "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注) |
ab | "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注) |
操作文件
功能 | 说明 |
f = open('file.txt','r+',encoding='utf-8') | encoding参数可以指定文件的编码 |
f.readline() | 读一行 |
f.readable() | 判断文件是否可读 |
fr.writable() | 判断文件是否可写 |
fr.encoding | 打印文件的编码 |
f.read() | 读取所有内容,大文件时不要用, 因为会把文件内容都读到内存中, 内存不够的话,会把内存撑爆 |
f.readlines() | 读取所有文件内容,返回一个list, 元素是每行的数据,大文件时不要用, 因为会把文件内容都读到内存中, 内存不够的话,会把内存撑爆 |
f.tell() | 获取当前文件的指针指向 |
f.seek(0) | 把当前文件指针指向哪 |
f.write('爱情证书') | 写入内容 |
f.fulsh() | 写入文件后,立即从内存中把数据写到磁盘中 |
f.truncate() | 清空文件内容 |
f.writelines(['爱情证书','孙燕姿']) | 将一个列表写入文件中 |
f.close() | 关闭文件 |
文件指针
要理解这文件覆不覆盖,其实理解好文件指针就好了,那么啥是文件指针呢?简单理解为输入时的小光标,那么假设有个空文件,那么在一开始指针是指向文件内容的开端的,伴随着读写的进行指针一步一步往后挪。
那么,对于单次打开某文件,其实文件指针都指向了最开头,我们看一个例子:
假设有一个txt文件(filetest.txt),其中的内容如下:
今年是佩奇年,平安健康! Python能做好多事! 今年要多写代码,写得多了也就熟练了!!
现在,我们写一段读的程序,
# coding=utf-8 import os # os.getcwd()获取当前路径,即项目工程的目录 f = open('filetest.txt','r') print("第一次读到的内容:\n", f.read()) print("第二次读到的内容:\n", f.read())
读取的结果如下:
第一次读到的内容: 今年是佩奇年,平安健康! Python能做好多事! 今年要多写代码,写得多了也就熟练了!! 第二次读到的内容:
我们发现,第二次没有读出来任何内容,这是为什么呢?
从程序本身来看,前后两次调用 f.read() 函数,本意是将文件内容读两遍,可是第二次未读到任何内容。
针对这样的问题,其实是文件有一个文件指针(也叫 文件游标)的概念。实际上,当我们打开(open)这个文件的时候,此时,文件指针就定位在了文件的开头,当第一次调用 f.read() 函数时,相当于从文件指针的当前位置(即:文件开头)将这个文件全部读取出来;当第二次调用 f.read() 的时候,实际上此时文件指针已经定位在了文件的末尾,再次读取的时候,指向的内容就为空了。
下面再看一个例子:
# coding=utf-8 import os # os.getcwd()获取当前路径,即项目工程的目录 f = open('filetest.txt','r') print("第一次读到的内容:\n", f.read(2)) # 读取 2 个字节的内容 print("第二次读到的内容:\n", f.read(4)) # 读取 4 个字节的内容
读取的结果如下:
第一次读到的内容: 今年 第二次读到的内容: 是佩奇年
我们看到第二次读取到的内容并不是 【 今年是佩】,而是【是佩奇年】 ,那也就是说,当我们第一次f.read(2)
的时候,当前文件指针已经定位到了第2个字节的位置,当第二次执行f.read(4)
的时候,实际上是从当前文件指针位置开始读取4个字节的内容。
下面接着看另一个例子:
# coding=utf-8 import os # os.getcwd()获取当前路径,即项目工程的目录 f = open('filetest.txt','r') print("第一次读到的内容:", f.readline()) print("第二次读到的内容:", f.readline())
经过之前的解释,相信大家也能知道这段程序读取的结果,应该是读取文件的前两行内容,实际结果也是如此:
第一次读到的内容:今年是佩奇年,平安健康! 第二次读到的内容:Python能做好多事!
现在我们改变一下需求,要求两次读取的内容都是 文件的第一行 内容,该怎么办?
此时,我们应该要做的是改变文件指针的位置。
如何改变文件指针呢?这里需要用到 seek() 函数,其语法:seek(offset, wherece)
offset:偏移量,即表示文件指针所在的当前位置要偏移的字节数
wherece: 0 - 从文件开头;1 - 文件的当前位置; 2 - 文件的末尾
也就是说:快速移动到文件末尾f.seek(0,2),快速移动到文件开头f.seek(0)
有了这个 seek() 函数,我们就可以实现上面的需求了,如下:
# coding=utf-8 import os # os.getcwd()获取当前路径,即项目工程的目录 f = open('filetest.txt','r') print("第一次读到的内容:", f.readline()) f.seek(0,0) # 重置文件指针到文件开头的第0个位置 print("第二次读到的内容:", f.readline())
结果如下:
第一次读到的内容:今年是佩奇年,平安健康! 第二次读到的内容:今年是佩奇年,平安健康!
那么,能不能查看当前文件指针的位置呢?答案是肯定的,就是 tell()
函数。
例如:
# coding=utf-8 import os # os.getcwd()获取当前路径,即项目工程的目录 f = open('filetest.txt','r') print("当前文件指针的位置:", f.tell()) print("第一次读到的内容:", f.readline()) print("当前文件指针的位置:", f.tell()) print("第二次读到的内容:", f.read(6)) print("当前文件指针的位置:", f.tell())
结果如下:
当前文件指针的位置:0 第一次读到的内容:今年是佩奇年,平安健康! 当前文件指针的位置:26 第二次读到的内容:Python 当前文件指针的位置:32
这里总结一下关于文件指针的运用方式:
file.seek(offset, wherece) # 移动 file 指针
file.seek(0,0) # 移动指针指文件最开头
file.seek(9,1) # 将文件指针从当前位置往后移动 9 个位置
file.seek(0,2) # 移动指针指文件最末尾
file.tell # 读取当前文件指针,每次统计都是从文件头到当前指针所在位置
f.truncate() # 截断,参照物永远都是文件开头