我们经常使用电脑磁盘中存储的图片、音乐、电影、doc文档等文件。例如使用播放器播放音乐和电影、用图片软件浏览图片、用Word软件查看或编辑doc文档等。那么,这些文件是如何形成的?在Python中又如何输出一个文件?
文件是如何形成的?
一般来说文件都与使用该文件的程序相关。例如,大家比较熟悉的Word软件,与它相关的就是扩展名为doc的文件。打开Word文档对内容编辑完成后,选择保存文件。
Word软件会把刚编辑的内容保存(写入)到一个被命名的文件中,写入的内容不仅仅是编辑的内容,也包括Word自身的段落、页面、字体字号等控制内容,Word会按照自己定义的数据结构(文件格式)来组织这些内容并写入到文件。
当Word读取该文件时,它会按照已定义的数据结构(文件格式)来解析读取的文件内容。因此,doc文档只能被Word程序使用,而不能被其它程序使用,除非Word公开了doc文件的数据结构(文件格式)。
用Python语言编写的程序,也可以生成和读取Word文件,前提是要了解Word的文件格式。Python文件对象提供了二种输出文件内容的方法,分别是write和writelines。其中write方法可以把文本数据或二进制数据块写入到文件;writelines把一个字符串列表写入到文件。下面分别予以说明。
使用write方法写入内容到文件
write方法把字符串或byte类型的数据写入到文件。当被写入文件以文本模式打开时,传入的参数应为字符串类型,当被写入文件以二进制模式打开时,传入的参数应为bytes类型。
writesize = fileobj.write (data);
其中data为要写入文件的数据,调用write方法写入data数据到文件后,write返回写入的字节数。需要注意到是,此时data数据并没有真正写入到文件,因为data数据被存储在缓冲区中,直到调用关闭或刷新缓冲区方法后,缓冲区的data数据才能实际写入到文件中。
文件对象刷新缓冲区的方法:
fileobj.flush();
例1:将字符串内容写入文本文件。
# 创建一个字符串对象
str = "课程以浅显易懂的语言,以常见的生活场景为案例,\
带领大家逐步进入计算机编程世界"
filename = "d://sample.txt"
try:
fp = open(filename,"w+")
print("%s 文件打开成功" % filename)
#写入文件
size = fp.write(str)
print("共写入 %d 个字节到 %s" % (size,filename))
#强制刷新缓冲区
fp.flush()
#关闭文件
fp.close()
except IOError:
print("%s文件打写入败 " % filename)
案例代码将str内容写入到sample.txt文件。要写入的sample.txt文件在磁盘中可能不存在,因此需要使用w+模式打开文件,当要打开的文件不存在时,使用w+模式会创建该文件。
write方法写入文件成功后,用Python提供的print函数输出写入的字节数,最后调用文件对象的close方法关闭文件。
案例2:将字符串内容写入二进制文件
#创建一个字符串对象
str = "课程以浅显易懂的语言,以常见的生活场景为案例,\
带领大家逐步进入计算机编程世界"
filename = "d://bsample.txt"
try:
#以二进制模式打开文件
fp = open(filename,"wb+")
print("%s 文件打开成功" % filename)
#写入文件
size = fp.write(str)
print("共写入 %d 个字节到 %s" % (size,filename))
#关闭文件
fp.close()
except IOError:
print("文件打开失败,%s文件不存在" % filename)
案例2的代码和案例1的代码几乎完全相同,不同的是文件的打开模式为wb+,该模式为二进制模式。当使用二进制模式打开文件时,write方法要求传入的参数类型为byte类型,如果传入的是字符串类型,就会发生编码错误。错误内容如下所示:
d://bsample.txt 文件打开成功
Traceback (most recent call last):
File "D:/pythoncode/t1.py", line 10, in <module>
size = fp.write(str)
TypeError: a bytes-like object is required, not 'str'
遇到此类问题,就需要对字符串类型的内容进行编码后再写入到文件。
#创建一个字符串对象
str = "课程以浅显易懂的语言,以常见的生活场景为案例,\
带领大家逐步进入计算机编程世界"
filename = "d://bsample.txt"
try:
#以二进制模式打开文件
fp = open(filename,"wb+")
print("%s 文件打开成功" % filename)
#写入文件
b = bytes(str,'utf-8')
size = fp.write(b)
print("共写入 %d 个字节到 %s" % (size,filename));
#关闭文件
fp.close()
except IOError:
print("文件打开失败,%s文件不存在" % filename)
使用Python提供内置bytes函数对str进行编码,编码格式选择utf-8即可,也可以使用字符串对象的encode方法对str进行编码。
b = str.encode('utf-8')
程序执行后输出结果如下所示:
d://bsample.txt 文件打开成功
共写入 124 个字节到 d://bsample.txt
案例3:将源文件内容输出到目标文件
#源文件路径
sourceFilename = "d://sample.jpg"
#目标文件路径
destFilename = "d://newsample.jpg"
try:
#打开源文件
fsource = open(sourceFilename,"rb")
print("%s 文件打开成功" % sourceFilename)
#读取源文件内容
content = fsource.read()
fsource.close()
#打开目标文件
fdest = open(destFilename,"wb+")
#将content写入目标文件
size = fdest.write(content)
fdest.close();
print("共写入 %d 个字节到 %s" % (size,destFilename))
except IOError:
print("文件打开失败,%s文件不存在" % sourceFilename)
案例代码声明了两个文件对象:一个是源文件对象,另一个是目标文件对象。源文件对象使用rb模式打开文件,使用read方法读取文件全部内容到content,目标文件使用wb+模式打开文件,使用write方法将content内容写入到目标文件。
使用writelines将列表内容写入文件
writelines可以把列表数据写入文件,列表数据可以作为参数传入。
fileobj.writelines (list);
list为传入的列表数据,不同于write方法,writelines写入成功后并不返回写入的字节数。
案例4:将列表数据写入文件
#创建一个列表数据
list = ['Java编程',"Python编程","PHP","JSP","MySQL"]
#待写入的文件名称
filename = "d://list.txt"
try:
#以w+模式打开文件
fp = open(filename,"w+");
print("%s 文件打开成功" % filename)
#写入文件
fp.writelines(list)
#关闭文件
fp.close()
except IOError:
print("文件打开失败,%s文件不存在" % filename)
案例代码创建一个list列表对象,待写入文件的名称为list.txt,文件以w+模式打开(如果list.txt不存在,则创建一个新的文件),文件打开成功后,调用writelines方法将list写入到list.txt。用记事本打开list.txt文件查看会发现,行结束符没有自动加入,这不是想要的输出结果。

需要在调用writelines方法之前,给list的每个元素加上换行符。
#创建一个列表数据
list = ['Java编程',"Python编程","PHP","JSP","MySQL"]
#待写入的文件名称
filename = "d://list.txt"
try:
#以w+模式打开文件
fp = open(filename,"w+");
#使用列表解析表达式为每个元素添加换行符
list=[ item+'\n' for item in list ]
print("%s 文件打开成功" % filename)
#写入文件
fp.writelines(list)
#关闭文件
fp.close()
except IOError:
print("文件打开失败,%s文件不存在" % filename)
用记事本打开list.txt文件查看会发现,行结束符已经加入。
