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()  # 截断,参照物永远都是文件开头

posted @ 2019-04-18 22:32  至死不渝的爱  阅读(139)  评论(0编辑  收藏  举报