夜光序言:
拿得起,放得下,那才叫潇洒。
正文:
6.2 读文本文件
6.2.1 目标
存储在文本文件中的数据要读出,教学目标是读出前一节存储在 students.txt 中的所有学生的数据。
6.2.2 读文本文件
1、读字符函数 read
read 函数的功能是从指定的文件中读字符,函数调用的形式为:
文件对象.read()
文件对象.read(n)
对于 read 函数的使用有以下几点说明:
(1) 在 read 函数调用中,读取的文件必须是已经以读方式打开的。
(2) 在文件内部有一个位置指针,用来指向文件的当前读的字符,在文件打开时,该位置指针总是指向文件的第一个字符。使用 read 函数后, 该位置指针将向后移动一个字符,每读一个字符,该位置指针就向后移动一个字符,因此可连续多次使用 read 函数读取多个字符。
(3) 如果不指定要读取的字符数 n,使用 read()读,则读到整个文件的内容;如果使用 read(n)指定要读取的字符数,那么就按要求读取 n 个字符;如果要读 n 个字符,而文件没有那么多字符,那么就读取所有文件内容。
(4) 如果文件指针已经到了文件的尾部,再读就返回一个空串。
在读取模式下,当遇到\n,\r 或\r\n 时都作为换行标识,并且统一转换为\n,作为文本输入的换行符。
例 6-2-1:保存文件 c:\abc.txt,打开文件读取全部内容,把其内容显示在屏幕上。
def writeFile():
fobj=open("c:\\abc.txt","wt")
fobj.write("abc\nxyz")
fobj.close()
def readFile():
fobj=open("c:\\abc.txt","rt")
s=fobj.read()
print(s)
fobj.close()
try:
writeFile()
readFile()
except Exception as err:
print(err)
注意程序中没有在 readFile()与 writeFile()中捕获异常,而是在主程序中统一捕获这两个函数中可能存在的异常。
执行结果:
abc
xyz
例 6-2-2:保存文件 c:\abc.txt,打开文件读取部分内容,把其内容显示在屏幕上。
def writeFile():
fobj=open("c:\\abc.txt","wt")
fobj.write("abc\nxyz")
fobj.close()
def readFile(n):
fobj=open("c:\\abc.txt","rt")
s=fobj.read(n)
print(s)
fobj.close()
try:
writeFile()
n=3
print(n)
readFile(n)
except Exception as err:
print(err)
执行程序,如图 6-2-1 所示是不同的 n 值读出的结果。
图 6-2-1
注意 n=4 读 4 个字符时 abc 后面有一个换行符'\n',只是我们看不见,但是的确存在,除了 abc 外,还有'\n',因此读出的是"abc\n",字符串长度为 4。n=5 时读出为"abc\nx"。
n=20 时要求读 20 个字符,但是文件只有 7 个字符,因此只读出全部的"abc\nxyz"。
例 6-2-3:保存文件 c:\abc.txt,打开文件一次读一个字符,读取全部。
如果文件指针已经到了文件的尾部,再读就返回一个空串,因此:
def writeFile():
fobj=open("c:\\abc.txt","wt")
fobj.write("abc\nxyz")
fobj.close()
def readFile():
fobj=open("c:\\abc.txt","rt")
goon=1
st=""
while goon==1:
s=fobj.read(1)
if s!="":
st=st+s
else:
goon=0
fobj.close()
print(st)
try:
writeFile()
readFile()
except Exception as err:
print(err)
结果:
abc
xyz
2、读取一行的函数 readline
如果要从文件中读取一行,那么:
文件对象.readline()
规则:
它返回一行字符串。readline()的规则是在文件中连续读取字符组成字符串,一直
读到'\n'字符或者读到文件尾部为止。
注意如果读到'\n',那么返回的字符串包含'\n'。
如果到了文件尾部,再次读就读到一个空字符串。
例 6-2-4:写入 abc 与 xyz 两行,读出显示。
def writeFile():
fobj=open("c:\\abc.txt","wt")
fobj.write("abc\nxyz")
fobj.close()
def readFile():
fobj=open("c:\\abc.txt","rt")
s=fobj.readline()
print(s,"length=",len(s))
s=fobj.readline()
print(s,"length=",len(s))
s=fobj.readline()
print(s,"length=",len(s))
fobj.close()
try:
writeFile()
readFile()
except Exception as err:
print(err)
结果:
abc
length= 4
xyz length= 3
length= 0
第一次读取一行为"abc\n",第二次读到"xyz",之后就到了文件尾部,再次读就读到一个空字符串。
例 6-2-5:保存文件 c:\abc.txt,打开文件一次读一行字符,读取全部。
利用文件指针到了文件尾部,再次读就读到一个空字符串的特性,我们可以设计下列函数一次读取一行,直到把全部读出为止:
def writeFile():
fobj=open("c:\\abc.txt","wt")
fobj.write("abc\nxyz")
fobj.close()
def readFile():
fobj=open("c:\\abc.txt","rt")
goon=1
st=""
while goon==1:
s=fobj.readline()
if s!="":
st=st+s
else:
goon=0
fobj.close()
print(st)
try:
writeFile()
readFile()
except Exception as err:
print(err)
结果:
abc
xyz
3、读取所有行的函数 readlines
如果要从文件中读取所有行,那么:
文件对象.readlines()
规则:
它返回所有的行字符串,每行是用"\n"分开的,而且一行的结尾如果是"\n"则包
含"\n"。
一般再次使用 for 循环从 readlines()中提取每一行。
例 6-2-6: 读取文本文件
def writeFile():
fobj = open("c:\\abc.txt", "wt")
fobj.write("abc\n 我们\nxyz")
fobj.close()
def readFile():
fobj = open("c:\\abc.txt", "rt")
for x in fobj.readlines():
print(x,end='')
fobj.close()
try:
writeFile()
readFile()
except Exception as err:
print(err)
结果:
abc
我们
xyz
6.2.3 【案例】从文件读出学生信息
1、案例描述
读出前一节中保存在 students.txt 中的全部学生记录。
2、案例分析
读出 students.txt 文件学生信息的关键代码如下:
f=open("student.txt","rt")
while True:
name=f.readline().strip("\n")
if name=="":
break
gender= f.readline().strip("\n")
age=float(f.readline().strip("\n"))
每次读取一行后使用 strip("\n")函数把这一行的"\n"去掉,因为 readline()函数读出的行是包含"\n"的。
3、案例代码
class Student:
def __init__(self,name,gender,age):
self.name=name
self.gender=gender
self.age=age
def show(self):
print(self.name,self.gender,self.age)
students=[]
try:
f=open("student.txt","rt")
while True:
name=f.readline().strip("\n")
if name=="":
break
gender= f.readline().strip("\n")
age=float(f.readline().strip("\n"))
students.append(Student(name,gender,age))
f.close()
for s in students:
s.show()
except Exception as err:
print(err)
结果:
夜光 男 1111.0
女神 女 21.0
程序中:
f.readline().strip("\n")
函数是读一行,但是不包含"\n"符号在内,因为 readline()函数读的结果是包含"\n"的,通过 strip("\n")把"\n"去掉。