关于文件操作
文件流程(把大象装冰箱里需要的步骤):
- 打开文件,得到文件句柄并将其赋值给变量,用于调用——开冰箱
- 通过文件句柄对文件进行操作——装大象
- 保存并关闭文件——关冰箱
文件操作中的重点:
- python,一切皆对象
- 能调用方法的一定是对象
- 文件操作首先要拿到唯一的文件句柄,通过文件句柄(文件对象)调用方法,完成指定操作。
- 文件操作在未加close方法时,python会给帮忙追加一个关闭,但什么时候关的不确定。为了保证数据的安全性,必须手动关闭!
- 推荐用with方法打开文件。
- 最常见的配合sys模块,os模块使用
open()方法:
对文件操作必不可少的工具之一。用于打开指定目录的文件,返回的是一个文件对象,当遇到打不开的文件时,会报错OSError。完整的格式:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file,必需,用于指定文件路径;
mode,可选,用于指定文件的打开方式(参数参照下文中的对照表),默认打开方式 t ;
buffering,可选,指定文件打开的缓冲,取值0,1, >1三个,0代表buffer关闭(只适用于二进制模式),1代表line buffer(只适用于文本模式),>1表示初始化的buffer大小
encoding,必需,不指定时可能不报错,但编码错误。用于指定文件读取的编码方式,常见的有UTF-8,GBK,UNICODE等
erros,可选,指定报错的级别,常用参数有strict,ignore,当取strict的时候,字符编码出现问题的时候,会报错,当取ignore的时候,编码出现问题,程序会忽略而过,继续执行
newline,可选,区分换行符,常用参数有None, \n, \r, ’’, ‘\r\n’ ,但是这个参数只对文本模式有效
closefd,可选,是与传入的文件参数有关,默认情况下为True,传入的file参数为文件的文件名,如果closefd为False,且给定文件描述符(而不是文件名),那么当文件关闭时底层文件描述符将保持打开。如果给定文件名,closefd必须为True(默认)。否则将引发错误。(更新ing)
opener,可选,可以指定打开文件所用的打开器。可选择自定义。
mode的参数选项及其作用
|
|
参数 |
作用 |
t |
文本模式 (默认)。 |
x |
写模式,新建一个文件,如果该文件已存在则会报错。 |
b |
二进制模式。 |
+ |
打开一个文件进行更新(可读可写)。 |
U |
通用换行模式(不推荐)。 |
r |
以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb |
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ |
打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ |
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w |
打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb |
以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ |
打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ |
以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a |
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ |
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
针对文件对象常用的操作方法(使用open函数拿到文件的操作句柄,使用操作句柄调用下面的方法实现文件的操作):
方法 |
功能描述 |
close() |
关闭文件。 |
fileno() |
返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 |
flush() |
强行向硬盘刷数据,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。没有flush时,会按照内存刷新规则向硬盘刷数据。 |
isatty() |
判断文件是否连接到一个终端设备,是返回 True,否则返回 False。 |
next() |
返回文件下一行。 |
read(n) |
从文件读取指定的字节数,如果未给定或为负则读取所有。 |
readline(n) |
以行为单位读取文件,读取当前光标所在的下一行,包括 "\n" 字符。两次readline()调用之间没有其他光标移动类的操作,则在上一次读取位置的基础上继续读取。 |
readlines(n) |
读取所有行以列表形式,若给定n>0,则是设置一次读多少字节,这是为了减轻读取压力。 |
readable() |
判断文件可读性,可读返回True,否则返回False |
seek() |
设置读取光标当前位置,注意,seek的单位是字节,不是但我们的能直接阅读的字符 |
seekable() |
光标是可移动的 |
tell() |
返回读取光标当前位置。注意的是在python2.x中,读取中文时tell(),read()方法一致;在python3.x中,读取中文的时候,tell()给出的是字节,read()方法按字符。不难理解,是由于Unicode和utf-8对中文的存储规定造成的。 |
truncate() |
截断,截取的字节通过size指定,默认为当前文件位置。 |
write() |
将字符串写入文件,返回的是写入的字符长度。 |
writelines() |
向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。 |
文件的读取,不论是用read(), readline(), readlines(), 还是通过 “for line in 文件句柄” ,都是在文件的光标当前位置为基础进行操作。换句话说,如果此时光标在文件最后,则都读不出任何内容。 “for line in 文件句柄”方式是对文件进行逐行操作,边拿边用,本质上for函数内部将文件对象(文件句柄)做成了一个迭代器。
文件的修改,在写入的时候,会将原内容直接覆盖。可借助新创建一个同类型的介质文件,用于转存修改后的文件内容,改动的做完改动再写入,未改动的内容直接copy写入。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # !/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 # #----------创建--------------- 5 # f=open('testing_file.txt','w') 6 # a=""" 7 # 大江东去,浪淘尽,千古风流人物。 8 # 故垒西边,人道是,三国周郎赤壁。 9 # 乱石穿空,惊涛拍岸,卷起千堆雪。 10 # 江山如画,一时多少豪杰。 11 # 遥想公瑾当年,小乔初嫁了,雄姿英发。 12 # 羽扇纶巾,谈笑间,樯橹灰飞烟灭。 13 # 故国神游,多情应笑我,早生华发。 14 # 人生如梦,一尊还酹江月。 15 # """ 16 # f.write(a) 17 # f.close() 18 19 # #------------读取修改--------------- 20 import os 21 # f1=open('testing_file.txt',"r+") 22 # f2=open('testing_file1.txt',"w+") 23 # 24 # for line in f1: 25 # data = line 26 # if ',' in data: 27 # data = data.replace(',','|') 28 # f2.write(data) 29 # print(f1.tell()) 30 # f1.seek(0) 31 # f2.seek(0) 32 # for line in f2: 33 # f1.write(line) 34 # f1.close() 35 # f2.close() 36 # os.remove(f2.name) 37 # os.rename(f2.name,f1.name) 38 39 40 41 # #-----------flush进度条----------------- 42 import time,sys 43 for i in range(20): 44 data = '*' 45 time.sleep(0.5) 46 sys.stdout.write(data) 47 sys.stdout.flush()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # !/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import sys 4 import os 5 """ 6 主要实现全局的修改和计数反馈,运行py文件同时传入对应的参数 7 传入参数:原内容,新内容,替换文件对象 8 输出结果:新文件、替换总数 9 """ 10 msg = sys.argv # 接收直接运行文件的时候,传入的参数值 11 12 print(""" 13 修改文件对象:%s 14 原内容:%s 15 新内容:%s 16 """%(msg[3],msg[1],msg[2])) 17 old_cont=msg[1] 18 new_cont=msg[2] 19 sum_num=0 20 21 if os.path.isfile(msg[3]): 22 f1 = open(msg[3],'r',encoding='utf-8') 23 f2 = open('mid_file.txt','w',encoding='utf-8') 24 for line in f1: 25 if old_cont in line: 26 sum_num+=line.count(old_cont) 27 line=line.replace(old_cont,new_cont) 28 f2.write(line) 29 f1.close() 30 f2.close() 31 os.remove(f1.name) 32 os.rename(f2.name,f1.name) 33 print("完成替换,共%s处"%sum_num)