文件读写
读写文件是最常见的I/O操作。Python内置了读写文件的函数I/O。
读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
打开和关闭文件
Python提供了必要的函数和方法进行默认情况下的文件基本操作。你可以用file对象做大部分的文件操作。
读文件
要以读文件的模式打开一个文件对象,使用Python内置的open()
函数,传入文件名和标示符。
open()函数语法:
file object = open(file_name [, access_mode][, buffering])
- file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。(如果只写文件名,当文件不存在时会在当前目录创建一个以该名命名的文件,但是如果写了具体路径,且文件名不存在,则会抛出一个IOError的错误,并且给出错误码和详细的信息告诉你文件不存在。)
- access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
- buffering:如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。
我们来试一下:
ffff=open('Users\jia\PytharmProjects\python007\ fo.txt','r')
标示符'r'表示读,这样,我们就成功地打开了一个文件。
模式 | 描述 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件只用于写入。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件只用于写入。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新内容将被写到原有内容之后。如果该文件不存在,创建新文件用于读写。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
File对象的属性
一个文件被打开后,你有一个file对象,你可以得到有关该文件的各种信息。
以下是和file对象相关的所有属性的列表:
属性 | 描述 |
file.closed | 如果文件已被关闭返回true,否则返回false。 |
file.mode | 返回被打开文件的访问模式。 |
file.name | 返回文件的名称 |
file.softspace | 如果用print输出后,必须跟一个空格符,则返回false,否则返回true。 |
# 打开一个文件
fo = open("foo.txt", "a+")
print ("文件名: ", fo.name)
print ("是否已关闭 : ", fo.closed)
print ("访问模式 : ", fo.mode)
print ("末尾是否强制加空格 : ", fo.softspace)
输出结果如下:
文件名: foo.txt
是否已关闭 : False
访问模式 : a+
末尾是否强制加空格 : 0
Close()方法
File对象的close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。
当一个文件对象的引用被重新指定给另一个文件时,Python会关闭之前的文件。用close()方法关闭文件是一个很好的习惯。
语法:
fileObject.close();
举个例子:
fo=open('fo.txt','r+')
print(fo.closed)
#这时输出False
fo.close()
print(fo.closed)
#这时输出True
读写文件--->read() 和write()
Write()方法
Write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
Write()方法不在字符串的结尾不添加换行符('\n'):
语法:
fileObject.write(string);
这里传递的参数及为要写入被打开文件中的内容,如:
fo=open('foo.txt','r+')
fo.write('Hello World')
fo.close() #要养成随手关闭的习惯
#这时打开foo.txt文件即可看见Hello World
read()方法
read()方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
语法:
fileObject.read([count]);
在这里,被传递的参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾。
我们综合的做一个练习:
fo=open('fo.txt','r+')
fo.write('Hello World! Python!')
#这里要注意的是,必须先执行一遍这个函数,让fo.txt中存在内容才可以执行read()函数
i=1
while len(txt)>0:
print('第'+str(i)+'读取到的数据:',txt,'当前位置',fo.tell())
i+=1
if i==7:
fo.seek(0,0)
txt=fo.read(3)
#seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
fo.close()
上述输出结果为:
第1读取到的数据:
Hello 当前位置 7
第2读取到的数据: Wo 当前位置 10
第3读取到的数据: rld 当前位置 13
第4读取到的数据: ! P 当前位置 16
第5读取到的数据: yth 当前位置 19
第6读取到的数据: on! 当前位置 22
第7读取到的数据:
He 当前位置 4 #当i==7时,指针回到最初的位置,即开始一遍循环
第8读取到的数据: llo 当前位置 7
第9读取到的数据: Wo 当前位置 10
第10读取到的数据: rld 当前位置 13
第11读取到的数据: ! P 当前位置 16
第12读取到的数据: yth 当前位置 19
第13读取到的数据: on! 当前位置 22
上面这个例子涉及到了两个函数tell()和seek(),tell()可以读取当前位置,而seek()可以改变当前指针的位置。
#seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
重命名与删除文件
Python的os模块提供了帮你执行文件处理操作的方法,比如重命名和删除文件。
要使用这个模块,你必须先导入它,然后可以调用相关的各种功能。
rename() 重命名:
os.rename(current_file_name, new_file_name)
先写原来的文件名,再写修改后的文件名。
remove() 删除文件:
os.remove(file_name)
所有文件都处在不同目录(文件夹)之下,但是python中的os模块有很多方法帮你处理:
mkdir()方法 -->在当前目录之中再创建一个目录 ,()中写新目录的名称。
chdir()方法 --> 更改当前目录的名称,()中写更改后的名称。
getcwd()方法 -->显示当前目录,用法是os.getcwd()
rmdir()方法 --> 删除目录,()中写要删除目录的名称,*注意的是,再删除目录之前要清空它里面的内容
removedirs()方法 --> 使用递归的方式删除文件夹,即删除当前文件夹,并尝试删除父级空文件夹,如下:
os.removedirs(父级文件/子级文件夹)
!!!使用上述方法时一定要引用os库!!!
相对路径和绝对路径,举个例子:
fo=open('a.txt','r')
#这是相对路径,意思是以现在操作的文件为位置,打开一个与操作文件同一个文档下名为a.txt的文档
foo=open('D:\\python\\b.txt','r')
#这是绝对路径,意为打开一个路径为D:\python\b.txt的文件
*注意:绝对路径中注意转译符,应打D:\\python\\b.txt
open(),中可以encoding='' 写需要的编码集
readline() 以行为单位读取 只读一行
readlines() 以行为单位 全部读取
我们举个例子,将下面一首诗中的三替换成四,并存储在另一个文档中:
“东风不来,三月的柳絮不飞
你的心如小小的寂寞的城
恰若青石的街道向晚
跫音不响,三月的春帷不揭
你的心是小小的窗扉紧掩 ”
# 现代诗保存在zzr.txt文档中
fo=open('zzr.txt','r+',encoding='gbk')
#将更改后的诗保存在zzk.txt文档中
foo=open('zzk.txt','w+')
lines=fo.readlines()
for li in lines:
foo.write(li.replace('三','四'))
#记得随手关闭文档
foo.close()
fo.close()
print('替换完成')
类似爬虫:我们将一个网页的源代码存储在一个html中:
from urllib import request
#首先需要从urllib中引入request
#请求打开一个url, 请求打开一个网络地址
response= request.urlopen('https://www.baidu.com')
#在本地创建一个文件
baidu=open('baidu.html','w+',encoding='utf-8')
#把服务器的响应 读取到htmls中
htmls=response.read()
#现在将读取到的代码写入baidu.txt中,注意的是这里写入的必须为str类型,并给代码decode一个编码集,将其转译为中文
baidu.write(str( htmls.decode('utf-8')))
print('读取完毕')
*********练习,将下面一篇文章以==分开,并区分老师学生,装在6个文档中,分别是老师123,学生123
老师:“河水往哪里流啊?”
学生:“大河向东流啊!”
老师:“天上有多少颗星星阿?”
学生:“天上的星星参北斗阿!”
========================
老师:“你给我滚出去!”
学生:“说走咱就走阿!”
老师:“你有病吧?”
学生:“你有我有全都有阿!”
========================
老师:“你再唱一句试试!”
学生:“路见不平一生吼阿!”
老师:“你信不信我奏你?”
学生:“该出手时就出手阿!”
老师:“我让你退学!”
学生:“风风火火闯九洲阿!”
代码如下:
def save_file(teacher,student,count):
file_name_teacher = 'teacher_' + str(count) + '.txt'
file_name_student = 'student_' + str(count) + '.txt'
teacher_file = open(file_name_teacher, 'w')
student_file = open(file_name_student, 'w')
teacher_file.writelines(teacher)
student_file.writelines(student)
teacher_file.close()
student_file.close()
def split_file(file_name):
teacher=[]
student=[]
count=1
f=open('demo.txt')
for each_line in f :
if each_line[:1]!='=':
(role,line_spoken)=each_line.split(':',1)
if role=='老师':
teacher.append(line_spoken)
if role=='学生':
student.append(line_spoken)
else:
save_file(teacher,student,count)
teacher=[]
student=[]
count+=1
save_file(teacher,student,count)
split_file('demo.txt')