文件读写
1、读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。
2、读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
打开文件:
在python中,打开文件使用open( )函数。其基本语法如下:
open(name[, mode[, buffering]])
参数说明:
name : 一个包含了你要访问的文件名称的字符串值(及其路径)。
mode : mode 决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
buffering : 如果 buffering 的值被设为 0,就不会有寄存。如果 buffering 的值取 1,访问文件时会寄存行。如果将 buffering 的值设为大于 1 的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。
注:使用open函数成功打开一个文件后,它会返回一个文件对象(File)。File对象代表计算机中的一个文件,是python中的另一种类型的值,就像我们熟悉的列表和字典。拿到这个对象后就可以读取或修改这个文件
例1:
TxtDemo = open("G:\\PythonDemo\\demo_2.txt") #所打开的文件不存在时
#上面代码的输出结果为:FileNotFoundError: [Errno 2] No such file or directory: 'G:\\PythonDemo\\demo_2.txt'
例1_1:
try:
TxtDemo = open("G:\\PythonDemo\\demo.txt")
print("目标文件为:",TxtDemo.name)
except FileNotFoundError:
print("目标文件不存在")
#上面代码的输出结果为:目标文件为: G:\PythonDemo\demo.txt
打开文件模式:
模式 | 描述 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
注:
1、b代表以二进制形式,+表示可读可写模式,b与+可以与其他三种模式组合使用(r表示读,w表示写,a表示加)
2、如果目标文件存在时,明确指定读模式和什么模式都不指定都是一样的;如果目标文件不存在时,最好指定"w+"模式
基本文件方法:
读:read()函数
read()方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。其语法如下:
fileObject.read([count])
1、fileObject为open()函数返回的File对象
2、count参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾。
例2:
path = "G:\\PythonDemo\\demo.txt"
txtdemo = open(path)
read_result = txtdemo.read(12)
print(read_result)
#上面代码的输出结果为:I am the sex
由上面的执行结果可以看出,如果read()函数后面带了参数时,就只会读取指定的字节数(空格和符号也算);若没有指定参数时,就会读取文件中的全部字符串
例3:
file = open("F:\\python\\test_file.txt")
while True:
str = file.read(1) #指定每次只读取一个字符
if not str:
break
print(str)
#循环读取文件中的一个字符,无字符时跳出循环(否则会一直循环读取)
写:write()函数
1、write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
2、write( )方法不会在字符串的结尾添加换行符('\n'),其语法如下:
fileObject.write(string)
例4:
path = "G:\\PythonDemo\\demo.txt"
txtdemo = open(path,"a+")
string = "On August 29, I met a girl and fell in love with her deeply__to_tutu"
txtdemo.write(string)
print(txtdemo.read()) #未执行该行
txtdemo.close()
例4_1:
path = "G:\\PythonDemo\\demo.txt"
txtdemo = open(path,"a")
string = "On August 29, I met a girl and fell in love with her deeply__tutu"
txtdemo.write(string)
txtdemo = open(path)
print(txtdemo.read())
#上面代码的输出结果为:On August 29, I met a girl and fell in love with her deeply__tutu
1、若打开文件时使用的是读模式,则此时就不能进行写入操作,即不能使用下面这种形式操作文件open(path,"rw")
2、由上面代码的执行结果来看只打开一次文件时不能同时进行读和写操作(即使使用了a+模式),若要同时进行读写操作时,需要在执行一项后再次打开文件并执行下一项
3、使用w(写)模式时,在写入字符串时会覆盖文件内已有的内容;若不想覆盖已有的内容则可以使用a(加)模式
4、如果打开的文件不存在,w模式和a模式就会创建一个新的空文件,然后执行写入或追加
换行写入:
在python中,用\n表示换行,若需要追加的内容在下一行,可以使用\n的方法
例5:
path = "G:\\PythonDemo\\demo.txt"
txtdemo = open(path,"a")
string = "On August 29, I met a girl and fell in love with her deeply__tutu"
txtdemo.write(string + "\n")
txtdemo.write("I"+ "\n")
txtdemo.write("love"+ "\n")
txtdemo.write("you"+ "\n")
备注:
若需要读写特定编码方式的文本,则需要给open()函数传入encoding参数;如需要读取GBK编码的文件时,则前面示例可以改为txtdemo = open(path,"r",encoding = "gbk")
读写行:
目前我们对文件的读操作是按字节读或整个读取,而写操作是全部覆写或追加,这样的操作在实际应用中不是很实用。python为我们提供了readline( ),readlines( ),writelines( )等方法用于行操作
read()函数:
语法如下:
file.read([size])
从文件读取指定的字节数,size如果未给定或为负则读取所有。
例6:
file = open("F:\\python\\test_file.txt")
print(file.read(2))
file.close()
readline()函数:
语法如下:
file.readline([size])
1、readline方法会从文件中单独读取一行,换行符为\n。readline方法如果返回一个空字符串,说明已经读取到了最后一行
2、readline方法也可以像read方法一样传入数值读取对应的字符数,传入小于0的数值表示整行都输出
例7:
file = open("F:\\python\\test_file.txt")
while True:
content = file.readline()
print(content)
if not content:
break
file.close()
#依次输出文件中的每一行,无内容时跳出循环
例7_1:
file = open("F:\\python\\test_file.txt")
content = file.readline()
print(content)
file.close()
#只会输出文件中的第一行
例7_2:
file = open("F:\\python\\test_file.txt")
content = file.readline(2)
print(content)
file.close()
#输出文件中第一行中的前两个字符(不会输出其他内容)
readlines()函数:
语法如下:
file.readlines([sizeint])
1、输出结果为一个字符串的列表。列表中的每个字符就是文件中的每一行,并且换行符也会被输出
2、readlines方法可以传入数值参数,当传入的数值小于列表中一个字符串的长度时,该字符串会被读取;当传入小于等于0的数值时,所有字符串都会被读取
例8:
file = open("F:\\python\\test_file.txt")
content = file.readlines() #content为一个字符串列表,可以用于迭代
print(content)
for world in content:
print(world)
file.close()
"""
['大家知道\n', '中国这些,\n', '你说什么']
大家知道
中国这些,
你说什么
"""
例8_1:
file = open("F:\\python\\test_file.txt")
content = file.readlines(3)
print(content)
for world in content:
print(world)
file.close()
"""
['大家知道\n']
大家知道
"""
writelines()函数:
语法如下:
file.writelines()
writelines方法与readlines方法相反,传给他一个字符串列表(任何序列或可迭代对象),它会把所有字符串写入文件。
例9:
file = open("F:\\python\\test_file.txt","a")
str_list = ["\nlove","tutu"] #在文末换行追加
file.writelines(str_list)
总结:
1、readline()方法:从字面意思可以看出,该方法每次读出一行内容,所以,读取时占用内存小,比较适合大文件,该方法返回一个字符串对象。(结合循环可实现循环读取所有行)
2、readlines()方法:读取整个文件所有行,保存在一个列表(list)变量中,每行作为一个元素,但读取大文件会比较占内存。
关闭文件:
1、当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。
2、由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:
例10:
try:
file = open("F:\\python\\test_file.txt")
print(file.readline())
finally:
if file:
file.close()
print(file.closed)
python中引入了with语句自动帮我们调用close()方法。使用with语句可以更简洁
例10_1:
with open("F:\\python\\test_file.txt") as f:
file = open("F:\\python\\test_file.txt","r")
print(file.readline())
文件迭代器:
从python2.2版本开始后,文件对象是可迭代的,这意味着可以直接在for循环中使用文件对象,从而进行迭代例11:
file = open("F:\\python\\test_file.txt","r")
for world in file:
print(world)
file.close()
print(file.closed)
#使用for循环对文件进行迭代后需要显式关闭文件
拓展:
File对象的属性:一个文件被打开后,你有一个file对象,你可以得到有关该文件的各种信息。
以下是和file对象相关的所有属性的列表:
属性 | 描述 |
file.closed | 返回true如果文件已被关闭,否则返回false。 |
file.mode | 返回被打开文件的访问模式。 |
file.name | 返回文件的名称。 |
file.softspace | 如果用print输出后,必须跟一个空格符,则返回false。否则返回true。 |
例12:
file = open("F:\\python\\test_file.txt","r")
print(file.closed)
print(file.mode)
print(file.name)
"""
False
r
F:\python\test_file.txt
"""
文件的读取和定位:
tell()方法:告诉你文件内的当前位置, 换句话说,下一次的读写会发生在文件开头这么多字节之后。
seek(offset [,from])方法:改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。
例13:
file = open("F:\\python\\test_file.txt","r")
str = file.read(2)
print("读取的字符串是 : ", str)
position = file.tell()
print("当前文件位置 : ", position)
position = file.seek(0, 0) #把指针再次重新定位到文件开头
print(file.tell())
string = file.read(3)
print("重新读取字符串 : ", string)
file.close()
"""
读取的字符串是 : 大家
当前文件位置 : 4
0
重新读取字符串 : 大家知
"""
备注:
1、文件指针相当于一个"书签",起到定位的作用
2、一个中文字符占用2个字节的空间,一个英文字母或符号占用一个字节
统计文件中某个字或单词出现的次数:
1、collections模块包含除内置list,dict,tuple 以外的其它容器数据类型。counter作为一个容器,可以跟踪相同的值增加了多少次。
2、counter支持三种形式的初始化,用counter的构造函数时可以提供一个元素序列或者一个包含键和计数的字典,还可以使用关键字参数将字符串名映射到计数。
例14:
import collections
file = open("F:\\python\\test_file.txt","r")
world = file.read().split('\n') #以换行符切片标准
m = collections.Counter(world)
print (world)
print (m)
print (m['lovetutu'])#字符a出现的次数
"""
['大家知道', '中国这些,', '你说什么', 'lovetutu', 'lovetutu']
Counter({'lovetutu': 2, '大家知道': 1, '中国这些,': 1, '你说什么': 1})
2
"""