Python基础知识_第10节_文件操作(IO技术)
文件操作(IO技术)
文本文件和二进制文件
- 文本文件:存储字符的文件,python默认为unicode解码,可以用记事本打开的文件。word文档不算纯文本文件,因为里面也可以放图片。
- 二进制文件:无法用记事本打开,必须用专用的软件解码。常见的有MP4视频文件、MP3 音频文件、JPG 图片、doc 文档等等。
文件操作相关模块概述
名称 | 说明 |
---|---|
io模块 | 文件流的输入和输出操作 input output |
os 模块 | 基本操作系统功能,包括文件操作 |
glob模块 | 查找符合特定规则的文件路径名 |
fnmatch模块 | 使用模式来匹配文件路径名 |
fileinput 模块 | 处理多个输入文件 |
filecmp模块 | 用于文件的比较 |
cvs模块 | 用于 csv文件处理 |
pickle 和 cPickle | 用于序列化和反序列化 |
xml包 | 用于 XML数据处理 |
bz2、gzip、 zipfile、 zlib、 tarfile | 用于处理压缩和解压缩文件(分别对应不同的算法) |
创建文件对象open()
- open(文件名,打开方式)
- 为了减少“\”的输入,可以使用原始字符串 r “文件名”
- f = open(r"d:\b.txt",“w”)
模式 | 描述 |
---|---|
r | 读read模式 |
w | 写write模式。如果文件不存在则创建;如果文件存在,则重写新内容; |
a | 追加append模式。如果文件不存在则创建;如果文件存在,则在文件末尾追加内容 |
b | 二进制binary模式(可与其他模式组合使用) |
+ | 读、写模式(可与其他模式组合使用) |
文本文件的写入
基本的文件写入操作
- 步骤
- 创建文件对象
- 写入数据
- 关闭文件对象
f = open(r"a.txt","a")
s = "itbaizhan\nsxt\n"
f.write(s)
f.close() # 一定要关闭文档
常用编码介绍
- 常用UTF-8。
- GB2312、GBK、GB8030都是中文解码。
中文乱码问题
- Windows操作系统默认编码时GBK,Linux操作系统默认的编码时UTF-8。
- Python默认编码为Unicode。
- 可以设置encoding为utf-8来使python在通过操作系统os来写入文件时,使用utf-8解码。
f = open(r"b.txt","w",encoding="utf-8")
f.write("尚学堂\n百战程序员\n")
f.close()
write()/writelines()写入数据
- write(a):把字符串a写入到文件中
- writelines(b):把字符串列表写入文件中,需要自己添加换行符。
f = open(r"d:\bb.txt","w",encoding="utf-8")
s = ["高淇\n","高老三\n","高老四\n"]
f.writelines(s)
f.close()
# 高淇
# 高老三
# 高老四
close()关闭文件流
- 必须要关闭文件对象。
- 可以结合异常机制finally确保关闭文件对象。
- 当调用close()方法时,首先会把缓冲区数据写入文件(也可以直接调用flush()方法),再关闭文件,释放文件对象。
try:
f = open(r"my01.txt","a")
str = "gaoqi"
f.write(str)
except BaseException as e:
print(e)
finally:
f.close()
with语句(上下文管理器)
- with自动帮忙还原。通常会使用with语句来读取文件。
s = ["高淇\n","高老三\n","高老五\n"]
with open(r"d:\bb.txt","w") as
f: f.writelines(s)
文本文件的读取
-
read(size):从文件中读取size个字符,并作为结果返回。如果没有size参数,则读取整个文件。读取到文件末尾,会返回空字符串。
-
readline():读取一行内容作为结果返回。读取到文件末尾,会返回空字符串。
-
readlines():文本文件中,每一行作为一个字符串存入列表中,返回该列表。
-
按行读取一个文件
# 用Readline方式。
with open(r"bb.txt","r") as f:
while True:
fragment = f.readline()
if fragment: # 如果读出来的行为空,则break
break
else:
print(fragment,end="")
# 使用迭代器(每次返回一行)读取文本文件,更推荐使用。
with open(r"d:\bb.txt","r") as f:
for a in f:
print(a,end="")
使用enumerate()函数和推导式生成列表操作每行增加行号
string.rstrip()去空白符
# 比较有意思,为文本文件每一行的末尾增加行号。
为文本文件每一行的末尾增加行号
with open("e.txt","r",encoding="utf-8") as f:
lines = f.readlines()
lines = [ line.rstrip()+" #"+str(index+1)+"\n" for index,line in enumerate(lines)] # enumerate推导式生成列表
# rstrip()去空白符
with open("e.txt","w",encoding="utf-8") as f:
f.writelines(lines)
二进制文件的读取和写入(图片文件拷贝)
- 需要在模式加入“b”:
- f = open(r"d:\a.txt", ‘wb’) #可写的、重写模式的二进制文件对象
- f = open(r"d:\a.txt", ‘ab’) #可写的、追加模式的二进制文件对象
- f = open(r"d:\a.txt", ‘rb’) #可读的二进制文件对象
# 读取图片文件,实现文件的拷贝
with open('aa.gif', 'rb') as f:
with open('aa_copy.gif', 'wb') as w:
for line in f.readlines():
w.write(line)
print('图片拷贝完成!')
文件对象的常用方法
方法名 | 说明 |
---|---|
read([size]) | 从文件中读取size 个字节或字符的内容返回。若省略[size],则读取到文件末尾,即一次读取文件所有内容 |
readline() | 从文本文件中读取一行内容 |
readlines() | 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回 |
write(str) | 将字符串 str内容写入文件 |
writelines(s) | 将字符串列表 s 写入文件文件,不添加换行符 |
seek(offset, whence) | 把文件指针移动到新的位置,offset表示相对于whence的多少个字节的偏移量;offset:为正往结束方向移动,为负往开始方向移动。whence:0: 从文件头(默认值)1:从当前位置 2:从文件尾 |
tell() | 返回文件指针的当前位置 |
truncate([size]) | 只留下指针前 size 个字节的内容,其余全部删除。如果没有传入 size,则当指针当前位置到文件末尾内容全部删除 |
flush() | 把缓冲区的内容写入文件,但不关闭文件 |
close() | 把缓冲区内容写入文件,同时关闭文件,释放文件对象相关资源 |
文件任意位置操作(seek()移动文件指针)
# seek()移动文件指针示例
with open("e.txt","r",encoding="utf-8") as f:
print("文件名是:{0}".format(f.name))
print(f.tell()) # 打印指针位置
print("读取的内容:{0}".format(str(f.readline())))
print(f.tell())
f.seek(0) # 指针移动到文件头
print("读取的内容:{0}".format(str(f.readline())))
# 文件名时:e.txt
# 0
# 读取的内容:我love u! #1
#
# 15
# 读取的内容:尚学堂 #2
#
使用pickle序列化
- 当把“对象/内存块的数据”保存到硬盘上,或者传输到其他的计算机上时,就需要对象的序列化和反序列化。
- pickle.dump(obj, file):obj就是要被序列化的对象,file 指的是存储的文件。
- pickle.load(file):从file读取数据,反序列化成对象
# 【操作】将对象序列化到文件中
import pickle
with open(r"d:\data.dat","wb") as f:
a1 = "高淇" a2 = 234
a3 = [20,30,40]
pickle.dump(a1,f)
pickle.dump(a2, f)
pickle.dump(a3, f)
# 【操作】将获得的数据反序列化成对象
with open(r"d:\data.dat","rb") as f:
a1 = pickle.load(f); a2 = pickle.load(f); a3 = pickle.load(f)
print(a1); print(a2); print(a3)
# 高淇
# 234
# [20, 30, 40]
CSV文件的操作
- 只能处理简单的字符串。
csv.reader对象和csv文件读取
- 【操作】csv.reader 对象于从csv 文件读取数据
import csv
with open(r"d:\a.csv") as a:
a_csv = csv.reader(a) # 创建csv对象。类似generator,只能使用一次。可以转化为二维列表。
headers = next(a_csv) #获得列表对象,包含标题行的信息
print(headers)
for row in a_csv: #循环打印各行内容
print(row)
csv.writer对象和csv文件写入
- 【操作】csv.writer 对象写一个csv 文件
import csv
with open(r"d:\b.csv","w") as b:
b_csv = csv.writer(b) # 创建csv对象
b_csv.writerow(["ID","姓名","年龄"]) # 写入单行
rows = [["1001", "西西", "3"], ["1003", "东东", "4"]]
b_csv.writerrows(rows) # 写入多行
os和os.path模板
- os模块可以直接对操作系统进行操作。
os 模块-调用操作系统命令
- os.system:调用系统的命令
- os.system(“notepad.exe”):调用记事本程序
- os.system(“ping www.baidu.com”):调用windows 系统ping命令,显示Ping值
- 含有中文字符,容易编码错误产生乱码。file – setting – encoding – GBK
- os.system(“cmd”):在pycharm里面打开cmd栏目
- os.startfile:打开已经被安装好了的、可执行文件
- os.startfile(r"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe"):打开微信
os 模块-文件和目录操作
- os模块下操作文件的方法
方法名 | 描述 |
---|---|
remove(path) | 删除指定的文件 |
rename(old, new) | 重命名文件或目录 |
stat(path) | 返回文件的所有属性:state |
listdir(path) | 返回path目录下的文件/子目录 |
- os模块下目录操作的方法
方法名 | 描述 |
---|---|
mkdir(path) | 创建目录 |
makedirs(path1/path2/path3/…) | 创建多级目录 |
rmdir(path) | 删除目录 |
removedirs(path1/path2…) | 删除多级目录 |
getcwd() | 返回当前工作目录:current work dir |
chdir(path) | 把path设为当前工作目录:change dir |
walk() | 遍历目录树 |
sep | 当前操作系统所使用的路径分隔符 |
# 【示例】os 模块:创建、删除目录、获取文件信息等
# coding=utf-8
import os
#############获取文件和文件夹相关的信息################
print(os.name) # windows->nt linux 和 unix->posix
print(os.sep) # windows->\ linux 和 unix->/
print(repr(os.linesep)) # windows->\r\n 和 linux-->\n\
print(os.stat("my02.py")) # 显示my02.py的各个信心
##############关于工作目录的操作###############
print(os.getcwd()) # 获得current workd dir
os.chdir("d:") # 改变当前的工作目录为:d:盘根目录
os.mkdir("书籍") # 在d:盘底下建了"书籍"这个子目录
os.rmdir("书籍") # 相对路径都是相对于当前的工作目录
################创建目录、创建多级目录、删除#############
os.makedirs("电影/港台/周星驰") # 可以同时创建、删除多个平行目录
os.removedirs("电影/港台/周星驰") # 只能删除空目录
os.makedirs("../音乐/香港/刘德华") # ../指的是上一级目录,在和本当前目录平行的位置新建目录
os.rename("电影","movie") # old,new
dirs = os.listdir("movie") # 把该目录下所有的目录、文件名,以list的形式返回
print(dirs)
os.path 模块
- os.path提供了更多目录相关的操作
方法 | 描述 |
---|---|
isabs(path) | 判断path 是否绝对路径 |
isdir(path) | 判断path 是否为目录 |
isfile(path) | 判断path 是否为文件 |
exists(path) | 判断指定路径的文件是否存在 |
getsize(filename) | 返回文件的大小 |
abspath(path) | 返回绝对路径 |
dirname§ | 返回目录的路径 |
getctime(filename) | 返回文件的创建时间 |
getatime(filename) | 返回文件的最后访问时间 |
getmtime(filename) | 返回文件的最后修改时间 |
walk(top,func,arg) | 递归方式遍历目录 |
join(path,*paths) | 连接多个path |
split(path) | 对路径进行分割,以列表形式返回 |
splitext(path) | 从路径中分割文件的扩展名 |
# 打印当前目录下所有的python文件
import os
from os import path # 代替import os.path
path = os.getcwd()
file_list = os.listdir(path) # 列出子目录、子文件
for filename in file_list:
if filename.endwith("py"): #!!!!!!!!!!!!!
print(filename)
################还可以写成推导式################
file_list2 = [filename for filenmae in os.listdir(path) if filename.endwith("py")]
for f in file_list2:
print(f, end="\t") # 去掉换行
os.walk递归遍历所有文件
- os.walk(path):返回一个3 个元素的元组,(dirpath, dirnames, filenames)
- dirpath:指定目录的路径
- dirnames:目录下的所有文件夹
- filenames:目录下的所有文件
# 用walk方法获得当前文件的全部absoulute目录
import os
all_files = []
path = os.getcwd()
list_files = os.walk(path)
for dirpath,dirnames,filenames in list_files:
for dir in dirnames:
all_files.append(os.path.join(dirpath,dir)) # dirpath当前目录的路径
for file in filenames:
all_files.append(os.path.join(dirpath,file))
shutil模块(拷贝和压缩)
-
用来压缩、解压缩。是对于os模块的补充。
-
拷贝
- 拷贝文件:shutil.copyfile(“源文件名”,“新拷贝的文件名”)
- 拷贝目录:shutil.copytree(“电影/学习”,“音乐”,ignore=shutil.ignore_patterns("*.html","*.htm"))
- 只有在没有“音乐”这个目录的时候才能使用。
- 通过ignore命令可以过滤掉一些文件类型。
-
压缩和解压缩
import shutil
import zipfile
# 压缩
# shutil方法
shutil.make_archive("音乐2/movie","zip","电影/学习") # 将"电影/学习"文件夹下所有内容压缩到"音乐2"文件夹下生成movie.zip
# zipfile方法
z = zipfile.ZipFile("a.zip","w") #压缩:将指定的多个文件压缩到一个zip文件
z.write("1.txt")
z.write("2.txt")
z.close()
# 解压缩
z2 = zipfile.ZipFile("a.zip","r")
z2.extractall("d:/") #设置解压的地址
z2.close()
通过递归recursion遍历目录下所有文件
import os
allfile = []
def getFiles(path,level):
childFiles = os.listdir(path)
for file in childFiles:
filepath = os.path.join(path,file) # 找出absolute目录。
if os.path.isdir(filepath): # 如果为目录,则recurse
getFiles(filepath,level+1) # getFile每调用一次,前面多缩进一格。
allfile.append("\t"*level+filepath) # 制造空格,使目录打印出来的位置和目录的层次相仿