8.1 文件和文件夹
配套的 Python 教学视频
8.1.1 文件
① 文件打开
文件对象 = open("文件名","访问模式")
访问模式如下:
'r'只读:如果文件不存在则报错,不支持写操作。
r+:如果文件不存在则报错,支持读也支持写。
'w'写入:如果文件不存在则新建文件,写入时覆盖原有内容。
w+:如果文件不存在则新建,可读可写。
'a'追加:如果文件不存在则新建文件,写入时在原有内容基础上追加新内容。
'a'追加:如果文件不存在则新建文件,可读可追加内容。
访问模式,默认是 ‘r’ 模式的。
二进制访问模式如下:
rb:只要文件不存在则报错,文件指针放在文件的开头,进行二进制读取。
rb+:可读写二进制。但是文件不存在则报错。
wb:只要文件不存在就新建文件,问价按指针在开头,用新内容覆盖原内容。写入二进制数据。
wb+:可读可写二进制数据。文件不存在则建立。
ab:文件不存在则建立。追加二进制数据。
ab+:可读可追加二进制数据。文件不存在则建立。
总结:r 是读 w 是覆盖写 a 是追加写。三者后面加上 b 代表对二进制数据进行操作,而非单纯的内容。加上 + 则代表扩展其功能,比如说以前没有 写功能,那么现在就让你带有写功能。
② 读写操作
文件对象.write("内容")
文件对象.read(读取长度)
指的是 读取固定长度的数据。如果省略此参数,则全部读取。切记 \n 换行符 也算是占用一个字节。
文件对象.readlines()
将所有行都读取出来,并且把 每一行 都封装为 列表的一个元素便于做细节处理。
文件对象.readline()
每次只能读取一行,并且随着 光标移动的位置,在进行下一次读取的时候,会读取 下一行。因为只读取一行,所以不带 \n 换行符。
③ 关闭和移动文件指针操作
文件对象.close()
文件对象.seek(偏移量,起始位置) 移动文件指针
文件对象.tell() 获取到当前光标的位置
起始位置:0代表开头位置,1代表当前位置,2代表文件结尾位置。
偏移量:比如起始位置是开头位置,偏移量是5,那么文件指针就在第六个字节上。
seek() 是实现随意读写的关键函数,即 我们想在哪里写或想在哪里读,都要配合 seek() 将光标移动到 那里进行其它的函数操作。
8.1.2 实战部分
创建文件并写入内容
a = open('1.txt','w')
a.write("""aaaa
bbbb
cccc""")
a.close()
读一下有多少个字符和读出内容
a = open('1.txt','w')
a.write("""aaaa
bbbb
cccc""")
a.close()#当 文件关闭后,再次打开时光标会重新刷新到正确的位置。
a = open('1.txt','r',encoding="utf-8")
print(len(a.read()))#此时光标 已经移动到 末尾
a.seek(0)#所以我们要把 光标 移动到 开头
print(a.read())#如果光标不在开头,则读取的结果肯定为空
a.close()
切记:无论是读取还是写入,都会使光标进行相应的移动,所以我们要时刻意识到 此时光标大概的位置。否则再往后操作时,就会出现自认为 出错的很多操作,岂不知 只是 光标的位置搞错了而已!!!
尝试 readlines() 和 readline()
a.seek(0)
列表 = a.readlines()
print(len(列表))
for i,x in enumerate(列表):
if(x.find('a') != -1):
del 列表[i]
print(列表)
处理所有元素的 \n,不用 replace()方法
a.seek(0)
列表 = a.readlines()
for i,x in enumerate(列表):
sub = x.find('\n')
if(sub != -1):
列表.insert(i+1,x[:sub])
del 列表[i]
print(列表)
print(列表)
a.seek(0)
print(a.readline())
print(a.tell())
a.close()
tell() 方法 可以直接取 现在的光标在第几个字节处。
光标处在 第六个字节的位置。下次 再进行操作 就要 从 第六个字节的位置开始了。
8.1.3 文件备份
实际上文件备份,是要讲一个 实战操作。就是 我们说的 提供文件具体路径,取 文件的名字。
文件路径 = r"C:\Users\muqua\Desktop\plugin\com.sdk.demo.vlw.dll"
endSub = 文件路径.rfind(".")
preSub = 文件路径.rfind("\\")
print(文件路径[preSub+1:endSub])
文件路径 = r"C:\Users\muqua\Desktop\plugin\com.sdk.demo.vlw.dll"
endSub = 文件路径.rfind(".")
preSub = 文件路径.rfind("\\")
print(文件路径[preSub+1:endSub])
备份路径 = 文件路径[:preSub] +"\\" +文件路径[preSub+1:endSub] + "_备份"+文件路径[endSub:]
print(备份路径)
旧文件 = open(文件路径,"rb")
备份文件 = open(备份路径,"wb")
while True:
读取数据 = 旧文件.read(1024)
if(len(读取数据) == 0):
print("写入数据ok!")
break
else:
备份文件.write(读取数据)
旧文件.close()
备份文件.close()
其实 也可以 不用 1024 这种 数据块 循环的 写入,可以直接 尝试 写入所有数据的。不过 可能会 遇到 缓存区 不够的情况,造成写入失败。备份文件.write(旧文件.read())
8.2.1 os 模块
文件夹的话,还是建议大家 用OS 模块。它既可以操作 文件又能操作 文件夹。
import os #导入os模块
os.rename('旧文件名','新文件名')
给文件改名,找不到 目标文件的话,就会 报错。
os.reanme('旧文件夹名','新文件夹名')
给文件夹改名,找不到 目标文件夹的话,就会 报错。
os.remove(目标文件名)
删除文件,不能删除文件夹!
os.rmdir(文件夹名字)
删除文件夹。
os.mkdir(文件夹的名字)
创建文件夹(如果文件夹已存在,则报错。)
os.getcwd() 这是很重要的函数,我们在实际开发中,其实用的最多的就是 程序当前的文件路径。因为我们写的程序,理应在 自己所处的文件夹内 进行 相关布置。
os.chdir(修改后的当前目录) 不建议使用!!我们如果想要 操作其它目录,直接 提供绝对路径即可,不要随意的更改 当前目录。这样在开发中 是很混乱的。
os.listdir(目录) 返回提供的目录 下 所有的东西,返回一个列表。如果不提供任何参数,则 默认 返回 当前目录 的 所有东西。在某些时候,需要用到 遍历它们。来找某个文件。非常实用的功能!
那么问题来了,我们说过 如果 找不到目标文件,可能有些方法会报错。但是我们的程序 不允许 报错,直接奔溃!怎么办呢?我们是不是要 进行 相关的 检测和处理呀!这个就是我们 下一章 要讲的 异常处理!
import os
#os.rename("1.txt","改1.txt")
#os.rename("文件夹1","改文件夹1")
#os.remove("3.txt")
#os.rmdir("文件夹2")
#os.mkdir("文件夹")
print(os.getcwd())
#os.chdir("C:\\") # 真的真的,不建议使用!!!
print(os.getcwd())
print(os.listdir())