一、文件操作简介

计算机系统分为:计算机硬件,操作系统,应用程序三部分。

我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知,应用程序是无法直接操作硬件的,这就用到了操作系统。操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的数据永久保存下来。

有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程:

open函数中模式参数的常用值:

open('文件路径')    默认的打开方式‘r’,默认的打开的编码是操作系统的默认编码

r  :读模式

w :写模式

a :追加模式

b :二进制模式(可添加到其他模式中使用)

+ :读/写模式((可添加到其他模式中使用)

备注:

1)一般来说,python默认处理的是文本文件。但是处理一些其他类型的文件(二进制文件),比如声音剪辑或者图像,那么可以使用‘b’模式来改变处理文件的方法。参数‘rb’可以用来读取一个二进制文件。

2)在实际工作过程中,很少遇到又读又写的事情,尽量不要使用‘+’模式,在python3里的文件指针非常乱,读写的时候占用两个不同的指针,所以很容易产生问题

文件操作过程:

1 #1.打开文件,得到文件句柄并赋值给一个变量
 2 f1=open(r'C:\a.txt',encoding='utf-8',mode='r')#开头‘r’代表元素字符串的意思,代表‘\’
 3 #2.通过句柄对文件进行操作
 4 data=f1.read()
 5 #3.关闭文件
 6 f1.close()
 7 #f1为python的变量,保存的文件内容,程序结束才能又python自动回收,文件关闭后不能在对文件进行读写
 8 #f1为文件句柄或文件对象,可以设置变量名:file,f_handle,file_handle,f_obj
 9 #open():打开的指令,windows的指令
10 #close():关闭文件,回收操作系统资源(不关闭会在内存中一直存在,切记)
11 #windows 的默认编码方式gbk,linux默认编码方式utf-8,max系统为utf-8

 二、文件的读

1 # pycharm 创建的文件默认都是utf-8   notepad++默认也是utf-8,但是可以修改编码方式,在格式菜单下修改
2 # EncodeDecodeErrot:编码错误
3 # 读操作:r模式:默认是rt文本读
4 #        rb模式:二进制模式,非文字类的文件操作
5 f1=open(r'register',encoding='utf-8')#不写mode,默认以读的形式打开
6 print(f1.read())
7 f1.close()

1、read()   文件内容全部读出

read()  不传参数 意味着读所有
            传参,如果是r方式打开的,参数指的是读多少个字符
            传参,如果是rb方式打开的,参数指的是读多少个字节

1 f1=open(r'a.txt',mode='rb')#rb模式不用写encoding,它是以bytes类型进行读取
 2 data1=f1.read()
 3 print(data1)
 4 data2=f1.read()#因为读文件有光标移动,第一次读之后,光标移动到最后,第二次读的时候读不到任何内容
 5 print(data2)
 6 f1.close()
 7 
 8 #read(n) r模式,按照字符读取 ; rb模式,按照字节读取
 9 f1=open(r'a.txt',encoding='utf-8')
10 print(f1.read(5))#r模式,按照字符读取
11 f1.close()
12 f1=open(r'a.txt',mode='rb')
13 print(f1.read(3))#rb模式,按照字节读取
14 f1.close()
15 
16 # unicode - --> bytes   encode()
17 # bytes - --> unicode   decode()
18 f1=open(r'a.txt',mode='rb')
19 data=f1.read(3)#写2个字节报错,必须与中文对应位数
20 print(data.decode('utf-8'))#rb模式,按照字节读取
21 f1.close()

2、readline()  按行读取

readline()   一行一行读 每次只读一行,不会自动停止

1 f1=open(r'a.txt',encoding='utf-8',mode='r')
2 print(f1.readline(),end='')#end可以取消print的换行效果
3 print(f1.readline(),end='')
4 f1.close()

3、readlines()  将每一行作为列表的元素,并返回这个列表(不常用)

1 readlines() 将每一行作为列表的元素,并返回这个列表
2 # 在文件比较小的时候可以用read和readlines读取,文件过大时,不建议使用这两种方式
3 f1=open(r'a.txt',mode='rb')
4 print(f1.readlines())
5 f1.close()

4、for 循环

for循环 一行一行读 从第一行开始 每次读一行 读到没有之后就停止

1 f1=open(r'a.txt',mode='rb')#f1这个文件句柄是迭代器,在内存当中只占一行的内存,for循环读取时,永远只在内存当中占一行
2 for line in f1:
3     print(line)
4 f1.close()

5、while 循环 不建议使用

1 with open(b'a.txt','r',encoding='utf-8') as f:
2     while True:
3         line=f.readline()
4         if len(line)==0:break
5         print(line)

三、文件的写

写操作:只能写字符串格式的,不能写数字

w模式:默认是wt文本写,如果文件不存在创建,存在则清空+覆盖

1、write()

1 f=open('a.txt','w',encoding='utf-8')
2 f.write('11111\n')
3 f.write('22222\n')
4 f.close()

2、writelines()

1 f=open('a.txt','w',encoding='utf-8')
2 f.writelines(['哈哈哈\n','hello','world'])
3 f.close()

3、writable 判断文件是否可写

1 f=open('a.txt','w',encoding='utf-8')
2 print(f.writable())#>>>True
3 f.close()

4、a模式 文件不存在则创建,文件存在在打开文件后则光标移动到文件末尾追加写

1 f=open('a.txt','a',encoding='utf-8')
2 f.write('sssss\n')
3 f.close()

5、b模式

1 #b模式 bytes 可以读文本、图片、视频,文件不存在报错
 2 #rb模式不能指定字符编码,否则报错
 3 with open(b'1.bmp','rb') as f:
 4     print(f.read())#输出图片的二进制编码
 5 with open(b'a.txt','rb') as f:
 6     print(f.read().decode('utf-8'))
 7 
 8 #rt 以文本形式读取
 9 with open(b'a.txt','rt',encoding='utf-8') as f:
10     print(f.read())
11 
12 #wb
13 with open(b'a.txt','wb') as f:
14     res='你好'.encode('utf-8')
15     print(res,type(res))
16     f.write(res)
17 
18 #ab 追加写
19 with open(b'a.txt','ab') as f:
20     res='你好'.encode('utf-8')
21     print(res,type(res))
22     f.write(res)

6、copy

1 #1、源文件大小的问题,一行一行读
 2 #2、文件打开模式的问题
 3 #flush()方法是用来刷新缓冲器的,即将缓冲区的数据立刻写入文件,同时清空缓冲区,不需要时被动的等待输入,
   #一般情况下,文件关闭后会自动刷新缓冲区,但是有时你需要在关闭前刷新它,这时就可以使用flush()方法
 4 with open(b'a.txt','rb') as read_f,\
 5       open('dstfile','wb') as write_f:
 6     for line in read_f:
 7         write_f.write(line)
 8         # write_f.flush()
 9 
10 #导入模块的好处就是可以把别人写的功能直接拿来用
11 #sys.argv是用来获取命令行参数的,sys.argv[0]表示代码本身路径,所以参数从1开始
12 import sys
13 _,src_file,dst_file=sys.argv
14 with open(src_file,'rb') as read_f,\
15       open(dst_file,'wb') as write_f:
16     for line in read_f:
17         write_f.write(line)
18         # write_f.flush()
19 
20 # encoding:utf-8
21 with open('a.txt','rt',encoding='utf-8') as f:
22     print(f.read())
23 
24 # with 程序运行完毕后自动关闭文件
25 with open(r'register',mode='rb') as f1:
26     pass
27 # with open()  as  自动关闭文件句柄   同一个with可以操作多个文件句柄

四、文件修改

1 #文件修改
 2 #1,打开原文件,产生文件句柄
 3 #2,创建新文件,产生文件句柄
 4 #3,读取原文件,进行修改,写入新文件
 5 #4,将源文件删除
 6 #5,新文件重命名原文件
 7 import os
 8 with open('info.txt','rt',encoding='utf-8') as read_f,open('.info.txt.swap','w',encoding='utf-8') as write_f:
 9     data=read_f.read()
10     write_f.write(data.replace('你好','hello'))
11     print(data)
12 os.remove('info.txt')
13 os.rename('.info.txt.swap','info.txt')
14 
15 import os
16 with open('info.txt','rt',encoding='utf-8') as read_f,open('.info.txt.swap','w',encoding='utf-8') as write_f:
17     for line in read_f:
18         if '你好' in line:
19             line=line.replace('你好','hello')
20         write_f.write(line)
21 os.remove('info.txt')
22 os.rename('.info.txt.swap','info.txt')

五、文件内光标移动

python 一个程序写入 一个程序读取_文件句柄

python 一个程序写入 一个程序读取_python_02

1 # tell()光标当前的位置(字节)
 2 with open('a.txt','r',encoding='utf-8') as f:
 3     data1=f.read()
 4     print(f.tell())
 5 
 6 #只有一种情况光标以字符为单位,文件以rt方式打开,read(3)
 7 with open('a.txt','rt',encoding='utf-8') as f:
 8     print(f.read(6))
 9     print(f.tell())
10 
11 #seek() 光标移动  按照字节去调整
12 with open('a.txt','rt',encoding='utf-8') as f:
13     print(f.read(6))
14     print(f.tell())
15     f.seek(0)
16     print(f.read(6))
17 
18 #seek(参数)另外两种模式需要在bytes模式下移动
19 #0模式  可以在t模式下使用
20 #1模式   相对位置移动
21 #2模式   以文件末尾为参照物移动 seek(0,2),调至最后
22 with open('a.txt','rb') as f:
23     f.seek(6,0)
24     print(f.read(6))#>>>b'\xbd\xa0\xe5\xa5\xbd'
25 
26 with open('a.txt','rb') as f:
27     print(f.read(6))
28     f.seek(2,1)
29     print(f.tell())
30     print(f.read().decode('utf-8'))
31 
32 with open('a.txt','rb') as f:
33     f.seek(-3,2)
34     print(f.tell())
35 
36 #tail -f access.log  打开文件读最新追加内容
37 import time
38 with open('access.log','rb') as f:
39     f.seek(0,2)
40     while True:
41         line=f.readline()
42         if line:
43             print(line,end='')
44         else:
45             time.sleep(0.05)
46 with open('access.log','a',encoding='utf-8') as f:
47     f.write('aaaaa\n')
48     f.flush()
49 
50 import time
51 with open('access.log','rb') as f:
52     f.seek(0,2)
53     while True:
54         line=f.readline()
55         if line:
56             print(line)
57         else:
58             time.sleep(2)
59 
60 #截断文件
61 with open('access.log','a',encoding='utf-8') as f:
62     f.truncate(3)#以文件开头为参照物,截断3字节

View Code