第1章 文件处理
1.1
文件操作流程
1、 打开文件,得到文件句柄并赋值给一个变量
2、 通过句柄对文件进行操作
3、 关闭文件
1.2
具体操作
1、打开文件,得到文件句柄并赋值给一个变量
f=open(‘db.txt‘,‘r‘,encoding=‘utf-8‘)
2、通过句柄对文件进行操作
data=f.read()
3、 关闭文件
f.close() #回收操作系统资源
1.3
流程分析
f=open(‘db.txt‘,‘r‘,encoding=‘utf-8‘)
1、由应用程序向操作系统发起系统调用:open(...)
2、操作系统打开该文件,并返回一个文件句柄给应用程序
3、应用程序将文件句柄赋值给变量f
1.4
资源回收
1、 打开一个文件包含两部分资源:
操作系统级打开的文件 和 应用程序的变量。
在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,方法是:
1) f.close() #回收操作系统级打开的文件;
2)
del f #回收应用程序级的变量;python解释器自动的垃圾回收机制已经替我们做了
注意:
1) del f 一定要发生在 f.close()之后,否则就会导致操作系统打开的文件没有关闭,浪费资源,记住在操作完毕文件后,一定要进行f.close
2)
打开文件的编码是以操作系统的编码为准的,除非open()指定encoding=‘编码‘ )
1.5
with 关键字
with的作用:上下文管理,它会帮我们来关闭文件(f.close())
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as f:
data=f.read()
### 支持同时管理多个文件
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as read_f,open(‘b.txt‘,‘r‘,encoding=‘utf-8‘) as write_f:
data=read_f.read()
write_f.write(data)
1.6
字符编码问题
f=open(...)是由操作系统打开文件,那么如果我们没有为open指定编码,那么打开文件的默认编码很明显是操作系统说了算了,操作系统会用自己的默认编码去打开文件:
在windows下是gbk,在linux下是utf-8。
这就用到了上节课讲的字符编码的知识:若要保证不乱码,文件以什么方式存的,就要以什么方式打开。
f=open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
第2章 打开文件的模式
文件句柄 = open(‘文件路径‘, ‘模式‘,‘字符编码‘)
2.1
文本模式(‘t‘,text mode(default)
r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f:
print(f.read())
w,只写模式【不可读;不存在则创建;存在则清空内容】
### 换行使用‘\n‘
with open(‘a.txt‘,‘w‘,encoding=‘utf-8‘) as f:
f.write(‘今天是2017.09.22\n‘)
f.write(‘今天是星期五\n‘)
今天是2017.09.22
今天是星期五
a, 只追加写模式【不可读;不存在则创建;存在则只追加内容】
with open(‘a.txt‘,‘a‘,encoding=‘utf-8‘)
as f:
f.write(‘111\n‘)
f.write(‘222\n‘)
f.write(‘333\n‘)
今天是2017.09.22
今天是星期五
111
222
333
2.2 二进制模式(‘b‘ binary mode)
对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
with open(‘yuanhao.jpg‘,mode=‘rb‘) as f:
print(f.read())
### 如果对文本使用b二进制模式操作,记得要解码成utf-8
with open(‘a.txt‘,mode=‘rb‘) as f:
data=f.read()
print(data.decode(‘utf-8‘))
### 写入文本格式的话,需要encode utf-8
with open(‘d.txt‘,mode=‘wb‘) as f:
f.write(‘哈哈哈hello‘.encode(‘utf-8‘))
2.3
了解模式
"+" 表示可以同时读写某个文件
r+, 读写【可读,可写】
w+,写读【可读,可写】
a+, 写读【可读,可写】
x, 只写模式【不可读;不存在则创建,存在则报错】
x+ ,写读【可读,可写】
第3章 操作文件的方法
3.1
掌握
3.1.1
read (读取)
f.read() #读取所有内容,光标移动到文件末尾
f.readline()
#读取一行内容,光标移动到第二行首部
f.readlines() #读取每一行内容,存放于列表中
### 读取所有内容,文件大的时候不要用 read
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f_read:
print(f_read.read())
今天是2017.09.22
今天是星期五
111
222
333
### 按行读取内容
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f_read:
print(f_read.readline())
print(f_read.readline())
今天是2017.09.22
今天是星期五
### 需要加上end=‘‘用来替换掉换行的 \n
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f_read:
print(f_read.readline(),end=‘‘) #一次读一行
print(f_read.readline(),end=‘‘)
今天是2017.09.22
今天是星期五
### 读所有,结果放入列表中
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f_read:
print(f_read.readlines()) #读所有,大文件的话会很卡
[‘今天是2017.09.22\n‘, ‘今天是星期五\n‘, ‘111\n‘, ‘222\n‘, ‘333\n‘]
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f_read:
print(f_read.readlines()[0])
今天是2017.09.22
3.1.2
write (写入)
f.write(‘1111\n222\n‘) #针对文本模式的写,需要自己写换行符
f.write(‘1111\n222\n‘.encode(‘utf-8‘)) #针对b模式的写,需要自己写换行符
f.writelines([‘333\n‘,‘444\n‘]) #文件模式
f.writelines([bytes(‘333\n‘,encoding=‘utf-8‘),‘444\n‘.encode(‘utf-8‘)]) #b模式
将列表中的内容写入文件:
l=[‘444\n‘,‘555\n‘,‘666\n‘]
with open(‘a.txt‘,‘a‘,encoding=‘utf-8‘)
as f_write:
for line
in l:
f_write.write(line)
今天是2017.09.22
今天是星期五
111
222
333
444
555
666
### 使用writeline方法
with open(‘a.txt‘,‘a‘,encoding=‘utf-8‘)
as f_write:
f_write.writelines([‘444\n‘,‘555\n‘,‘666\n‘])
3.1.3
#遍历文件z
with open(‘a.txt‘,encoding=‘utf-8‘) as f:
#不推荐使用
# lines=f.readlines()
# for line in lines:
#
print(line,end=‘‘)
### 推荐使用
for line in f:
print(line,end=‘‘)
3.2
了解
f.readable() #文件是否可读
f.writable() #文件是否可读
f.closed #文件是否关闭
f.encoding #如果文件打开模式为b,则没有该属性
f.flush() #立刻将文件内容从内存刷到硬盘
第4章 文件操作的其他方法
4.1
read(n)
### 以文本的模式读文件,n代表的是字符的个数
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f:
data=f.read(3)
print(data)
今天是
### 以b的模式读文件,n代表的是字节的个数
with open(‘a.txt‘,‘rb‘)
as f:
data=f.read(3)
print(f.tell())
print(data.decode(‘utf-8‘))
3
今
4.2
tell 返回光标位置
### tell:告诉当前光标的位置
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f:
data=f.read(3)
print(f.tell())
print(data)
9
今天是
4.3
seek 移动光标
fileObject.seek(offset[, whence])
offset -- 开始的偏移量,也就是代表需要移动偏移的字节数
whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
as f:
data1=f.read()
print(‘first: ‘,data1)
print(f.tell())
#获取当前光标位置
f.seek(0) #移动到文件开头
data2 = f.read() #由于光标移动到文件开头,所以文件又完全输出一次
print(‘second: ‘,data2)
first: abc
efd
12
second: abc
efd
第5章 文件的修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)
e.txt >>>
alex say i have on tesla
my name is alex
alex is good
alex xxxx hahaha alex
### 方式一(占用内存过大,仅适用于小文件):把硬盘中文件的数据全部读入内存,然后在内存里进行修改,最后保存
import os
with open(‘e.txt‘,‘r‘,encoding=‘utf-8‘)
as f_read,\
open(‘.e.txt.swap‘,‘w‘,encoding=‘utf-8‘)
as f_write:
data=f_read.read()
data=data.replace(‘alex‘,‘sb‘)
f_write.write(data)
os.remove(‘e.txt‘)
os.rename(‘.e.txt.swap‘,‘e.txt‘)
### 方式二:一行一行地读,一行一行地改
import os
with open(‘e.txt‘,‘r‘,encoding=‘utf-8‘)
as f_read ,open(‘e.txt.swap‘,‘w‘,encoding=‘utf-8‘)
as f_write:
for n
in f_read:
data=n.replace(‘sb‘,‘alex‘) ### 读一行
f_write.write(data) ### 改一行
os.remove(‘e.txt‘)
os.rename(‘e.txt.swap‘,‘e.txt‘)
第6章 把文件档数据库
db.txt>>>
1,peigen1,38,male,1234563378
2,peigen2,28,female,1234335678
3,peigen3,18,male,123145678
4,peigen4,8,male,1234115678
5,peigen5,48,female,1232245678
6,peigen6,58,male,1234335678
with open(‘db.txt‘,‘r‘,encoding=‘utf-8‘)
as f:
for line
in f:
user_l=line.split(‘,‘)
print(user_l[1],int(user_l[2]))
peigen1 38
peigen2 28
peigen3 18
peigen4 8
peigen5 48
peigen6 58