一:文件简介:
(1)简述:在未涉及到对文件操作以前,我们的编写的程序都需要在每次运行的时候重新输入数据,这是因为所有我们编写的程序中变量所指向的数据都存储在内存中,而这些数据在程序停止运行以后都会消失。如果我们想多次运行程序并存储数据,那么就必须对数据进行保存。数据可以保存在文件中,存储在计算机的硬盘上,如此一来,即使我们停止程序数据也将依旧存在。在实际运用中将数据存在文件中是十分普遍而必要的,不论是简单的文本文件,还是图像,表格甚至游戏数据,都需要存储在文件中满足输入和读取的需求。
(2)文件类型:首先我们区分文本文件和二进制文件。但我们知道,文件在计算机硬盘上存储的时候都是以二进制形式储存的,所以实际上文本文件也是一种特殊的二进制文件。我们一般说能够用文本编辑器打开的就是文本文件,不能由文本编辑器打开的,存储在其中的数据只能由程序读取的是二进制文件。但是这样的区别实际上只是从读取软件的方面进行了区分。广义上文本文件就是二进制文件,如果要从狭义的角度进行划分,那么首先:
①文本文件只能存储char型字符变量,二进制文件可以储存char/int/float…类型的各种变量
②文本文件的数据通常是固定长度的,进制文件数据长度可变。比如ASCII解释形式,每条数据(每个字符)都是一个字节,二进制文件中int占4个字节,float占8个字节。
③文本文件的解释形式是ASCII和Unicode,这是已经确定的。实际上,字符数据本身在内存中就经过了编码,所以无论是二进制还是文本形式都是一样的,但是当文本文件中包含数字数据时,这些数字将被转化为对应的一串字符;而二进制文件中数据没有转化为对应的字符串。这也是为什么当你打开二进制文件时出现了一堆乱码,但是并不是全是乱码。其中也有正常保存的地方,那些地方的数据全是字符型的数据,而对应int,float型的数据编码就完全是乱码了。
(3)文件读取方式:大多数的编程语言中文件读取方式也分为两种:顺序读取和直接读取。当顺序读取文件时,你可以访问文件从头到尾所有的数据,且当你想访问某条数据时,你必须访问这条数据之前的所有数据;直接读取文件时你可以直接跳转到文件中的任何数据而无需读取之前的数据。那么这里我将介绍顺序读取方式。
(4)文件对象:为了使程序和硬盘上的文件一起工作,程序必须创建内存中的文件对象。一个文件对象是与特定文件关联的一个对象,可以为程序提供使用该文件的方法。在程序中,一个变量引用了文件对象,该变量就可以用于在文件上的各种操作。对于,文件对象,还有一些很需要注意的点,我将它写在下面,读取文件和写入文件之后。
二:打开文件
在python中我们使用open()函数打开文件,open()函数创建一个文件对象并与磁盘上的文件相连接。一般形式为:
file_variable = open(filename,mode)
其中,file_virable是引用该文件对象的变量名(文件名要加上文件类型后缀如txt);filename是指向文件名称的字符串;而mode是打开文件的模式。
(1)指定文件位置
如果.py文件和文本文件在同一文件目录下,直接输入文件名即可。如果在计算机其他位置,在参数中要指定路径并在之前加上前缀字符‘r’,例如:
file_virable = open(r’C:\Users\Blank\test.txt’,‘r’)
(2)如果你之前学过Linux操作系统你就会发现这些东西似曾相识,我将展示三种常用的打开模式:
模式 | 描述 |
‘r’ | 以只读模式(read only)模式打开文件。文件不能被修改或写入。 |
‘w’ | 以写入模式(write)模式打开文件。如果文件已存在,则清空文件。若不存在则创建该文件 |
‘a’ | 以追加(add)模式打开文件。所写入文件的数据将追加到文件末尾,若文件不存在则创建该文件 |
三:读取文件
我们在之前已经提到了关于函数对象的定义,那么如果你已经学习过面向对象编程,那么你一定知道一种类型的函数–方法,方法是属于对象的函数。如果想对文件进行操作,我们也可以使用文件对象的方法。
如果想从一个文件中读取数据,那么首先你应该用‘r’模式打开文件,可以使用read()方法,read方法将文件全部内容写入内存,调用read方法时会以字符串形式返回文件内容。我已经创建了一个文本文件numbers.txt
下面我将用一个范例调用文件内容:
infile = open('numbers.txt','r')
content = infile.read()
print(content)
执行结果为:
虽然read方法能让你轻松的读取一个文件的全部内容,但是很多时候我们需要对文件的单个条目进行操作,那么这个时候,我们可以使用readLine读取一行以‘\n’结尾的数据,该方法返回包含‘\n’的字符串。且须知,readLine方法每次调用都会自动读取下一行的内容,不需要程序员自己进行跳转操作,比如刚刚那个范例,如果用readLine()方法来编写的话将是:
infile = open('numbers.txt','r')
line1 = infile.readline()
line2 = infile.readline()
print(line1)
print(line2)
我们之前已经说过,readLine函数会返回带有’\n’的字符串,所以我们使用print函数输出时会发现有空行出现:
如果我们想删除换行符,我们可以使用在字符串板块讲过的rstrip()函数,如:
infile = open('numbers.txt','r')
line1 = infile.readline().rstrip('\n') #这里我使用了连续的.操作符,使得代码长度变短
line2 = infile.readline().rstrip('\n')
print(line1)
print(line2)
这样输出结果就会是:
我们也可以利用循环读取数据,比如我们已知文件的末尾readLine会返回一个空串,所有将此作为循环判断条件可以实现循环,比如刚刚的例子,如果我想用循环进行读取那么代码为:
infile = open('numbers.txt','r')
line = infile.readline().rstrip('\n')
while line != '': #判断非空串
print(line)
line = infile.readline().rstrip('\n') #重新将新的数据赋给变量line
这样的输出结果跟上面一样
如果我们想更优雅的使用循环,那么我们不妨使用有迭代器的for循环,这样就可以不必判断文件是否结束,代码为:
infile = open('numbers.txt','r')
for line in infile:
print(line.rstrip('\n'))
这样也能获得和上面一样的结果
四:写入文件
如果我们想将数据写入文件中,那么应该以‘w’或‘a’模式打开文件,否则会产生错误。与读取文件类似,写入数据也有一个叫做write()的方法可将数据写入文件,一般形式为:
file_virable.write(string)
不难看出,我们写入其中数据应该是字符串形式,如果我们想将非字符串形式的数据输入其中,那么我们应该加上强制类型转化str(),且输入其中的数据,如果想要有良好的查看体验,那么一定要自己加上换行符’\n’。例如刚刚那个例子,我想在原来的文件下面加上两串“1 2 3 4”的字符串该怎么做呢?
infile = open('numbers.txt','a')
line = "1 2 3 4"
for n in range(2):
infile.write(line+'\n')
infile.close()
但是我们运行以后发现,文本编辑器中我们的数据是:
这是因为我们没有注意到原来的文本文件末尾没有换行的原因导致的,我们在之前加上换行符‘\n’即可改正。所以对文件操作一定要熟悉文件的储存格式和样式,这样才能选择适合的方法修改文件。比如我的一个文本文件stuff.txt,每三行分别表示姓名,年龄,工号,那么文本编辑器中的形式是:
如果我想准确显示这些信息,我的代码可以是:
infile = open('stuff.txt','r')
name = infile.readline().rstrip('\n')
while name != '':
age = infile.readline().rstrip('\n')
id = infile.readline().rstrip('\n')
print('Name:',name)
print('Age:',age)
print('ID:',id)
print()
name = infile.readline().rstrip('\n')
执行结果将是:
五:关闭文件
程序结束后,应该使用file_virable.close()来关闭文件,断开文件和程序的连接。