工程师们大家好,配套免费视频(平时上班周末录制)
1.os目录操作
文件操作第一个模块是os
使用之前需要 import os进行导入,为了方便测试在D盘下新建文件夹pythonFile/os/a.txt
import os
print(os.getcwd()) # C:\Users\xuewenjun\PycharmProjects\pythonProject当前工作目录路径
# 文件操作
# D://xxxx//xxx 这种从某个具体盘符开始的称为绝对路径
# a.txt称为相对路径 python会从当前工作目录下面找
dir_name = 'D://pythonFile//os' # 定义一个目录
file_name = 'a.txt' # 定义一个文件
full_path = os.path.join(dir_name, file_name) # 路径链接 D://pythonFile//os//a.txt
# 1.os.path.isabs() 判断是否为绝对路径 返回boolean值
print(os.path.isabs(dir_name)) # True 完整路径返回true
print(os.path.isabs(file_name)) # False文件名字 不是完整路径
print(os.path.isabs(full_path)) # True 组合后是完整路径D://pythonFile//os//a.txt
# 2.os.path.exists() 判断是否存在
print(os.path.exists(dir_name)) # True
print(os.path.exists(file_name)) # False 因为只有文件名字 未指定绝对路径 那么会相对路径在当前路径下面找
print(os.path.exists(full_path)) # True 绝对路径 下存在文件
# 3.os.path.isdir() 判断当前文件是否是目录
print(os.path.isdir(dir_name)) # True
print(os.path.isdir(file_name)) # False 当前工作目录都没有这个文件 没法判断
print(os.path.isdir(full_path)) # False 最终指向a.txt不是目录
# 4.os.path.isfile() 判断当前是否是 文件
print(os.path.isfile(dir_name)) # False
print(os.path.isfile(file_name)) # False当前工作目录都没有这个文件 没法判断
print(os.path.isfile(full_path)) # True
# 5.os.path.split() 分割文件夹名与文件名 返回元组
split = os.path.split(full_path)
print(split) # ('D://pythonFile//os', 'a.txt')
# 6.os.path.splitdrive() windows下分割盘符
splitdrive = os.path.splitdrive(full_path)
print(splitdrive) # ('D:', '//pythonFile//os\\a.txt')
# 7.os.path.splitext() 分割文件名与扩展名
print(os.path.splitext(file_name)) # ('a', '.txt')
print(os.path.splitext(full_path)) # ('D://pythonFile//os\\a', '.txt')
# 8.os.chdir() 方法用于改变当前工作目录到指定的路径。 不演示了
# 9.os.getcwd() 获得当前工作目录
# 10.os.listdir() 列出文件夹下面所有文件
print(os.listdir()) # ['.idea', 'main.py', 'test.py'] 不写就是当前目录下
print(os.listdir(dir_name)) # ['a.txt'] 指定目录下
# 11.os.mkdir() 创建文件夹 单个
# os.mkdir('abc') # 相对路径 就是在当前工作目录下面创建文件夹abc 如果文件存在了会报错
# os.mkdir('D://pythonFile//os//abc') # 指定目录下创建
# 12.os.mkdirs() 创建多级目录
# os.makedirs('a/b/c') # 当前工作目录下面创建多级目录
# 13.os.rmdir() 删除空文件夹 注意:必须为空文件夹 如需删除文件夹及其下
# os.rmdir('a') # 删除当前工作目录下面的a :OSError: [WinError 145] 目录不是空的。: 'a'
# 14.os.remove() # 删除单一文件
# 15.os.rename() 重命名文件 文件夹
os.rename('abc', 'aaa') # 没有文件会报错FileNotFoundError: [WinError 2] 系统找不到指定的文件。: 'abc' -> 'aaa'
#
2.目录练习
1.指定一个路径,打印下面所有的文件夹与文件 包含子文件(只能使用os)
import os
def list_dir(path):
# 如果是一个文件 那么直接打印
if os.path.isfile(path):
print(path)
return # 方法结束
# 如果是一个目录获得下面所有的文件夹与文件
listdir = os.listdir(path)
if listdir: # 如果不是空文件夹
for f in listdir: # 遍历
# 遍历这个listdir 发现又是一个路径 又需要打印
# 但是我们已经有一个方法可以传递一个路径就能打印
# 于是直接调用该方法 , 方法调用方法就是递归
list_dir(path + '\\' + f)
print(path) # 方法结束
list_dir(os.getcwd())
上面用到了递归,你会发现因为不知道文件有多少级,用循环还不知道咋循环,还只能用递归
方法自己调用自己就形成了递归,递归一定要注意,参数要改变,要有出口,也就是递归结束大家可以多找点练习题练习
2.递归删除一个路径
import os
def del_dir(dir_path):
if os.path.isfile(dir_path): # 如果是file直接删除
os.remove(dir_path)
return
listdir = os.listdir(dir_path)
if listdir:
for d in listdir:
del_dir(dir_path + '\\' + d) # 递归
os.rmdir(dir_path)
del_dir('D://pythonFile')
3.shutil操作
shutil.rmtree(‘a’)删除 a及其下所有文件
import shutil
shutil.rmtree('D:\pythonFile') # 删除pythonFile文件夹及其所有文件
shutil.copyfile(“old”,“new”) # 复制文件,都只能是文件
import shutil
# 把当前工作目录下面的a.txt复制到b.txt 会复制内容
shutil.copyfile('a.txt', 'b.txt')
shutil.copytree(“old”,“new”)# 复制文件夹,都只能是目录,且new必须不存在
import shutil
# 把当前工作目录下面的a文件夹复制到b文件夹 内部的文件一起复制
shutil.copytree('a', 'b')
shutil.copy(“old”,“new”) old必须是文件 new可以是文件或者文件夹 文件就创建文件,文件夹就复制过去(文件夹不存在报错)
import shutil
# 把a.txt复制到b目录下
shutil.copy('a.txt', 'b')
# 把a.txt复制为c.txt
shutil.copy('a.txt', 'c.txt')
shutil.move(“old”,“new”) # 移动文件/文件夹至 new 文件夹中 old是文件夹或者文件 new是文件夹
import shutil
# 移动b.txt去a目录下
# shutil.move('b.txt', 'a') # 如果目标下面存在报错 shutil.Error: Destination path 'a\b.txt' already exists
# 移动b目录去a目录下
shutil.move('b', 'a') # 如果a下面存在了 就会报错
4.文件操作
在当前工作目录下新建a.txt
天青色等烟雨
而我在等你
open r模式:
# 获得当前目录下a.txt的文件句柄 r表示只读模式
f1 = open('a.txt', 'r', encoding='utf-8')
read = f1.read()
print(read)
# f1.write('阿萨大师') # 因为是只读模式报错io.UnsupportedOperation: not writable
f1.close()
# f1.read() # 已经关闭了 不能再操作了ValueError: I/O operation on closed file.
open w模式:
# 获得当前目录下junge.txt的文件句柄 w表示只写入模式
f1 = open('junge.txt', 'w', encoding='utf-8')
# f1.read() # io.UnsupportedOperation: not readable
f1.write('凭君莫话封侯事,一将功成万骨枯')
f1.close()
# junge.txt不存在就会创建 然后写入
# junge.txt 如果存在会覆盖掉里面的内容
open a模式:
# 获得当前目录下junge.txt的文件句柄 a表示追加模式
f1 = open('junge.txt', 'a', encoding='utf-8')
# f1.read() # io.UnsupportedOperation: not readable
f1.write('凭君莫话封侯事,一将功成万骨枯')
f1.close()
# junge.txt如果不存在会创建文件 然后写入
# junge.txt如果存在后在原来内容后面追加现在写入的内容
open r+模式:
'''
junge.txt内容如下:
后宫佳丽三千人
铁杵磨成绣花针
'''
# r+模式文件不存在会报错
f1 = open('junge.txt', 'r+', encoding='gbk') # 因为我是手写的junge.txt用的是我默认的gbk编码
# r+模式建议先读后写
print(f'文件指针位置:{f1.tell()}') # 文件指针位置:0
print(f1.readline()) # 后宫佳丽三千人
print(f'文件指针位置:{f1.tell()}') # 文件指针位置:16 GBK中文占两个字符7*2+\n(换行符两个字符)
f1.write('从此君王不早朝') # 虽然现在指针在16 但是写的时候依然会去末尾 追加 就不会出错
print(f1.tell()) # 44最后了 21中文*2+\n
print(f1.seek(0)) # 因为上面读取了一行readline 导致指针移动了 如果需要从头开始读 可以手动设置指针
print(f1.read())
f1.close()
# 如果先写后读
# r+:先读后写的话是在原有文本后添加, 因为读完后类指针已经在最末尾了,
# 如果是先写后读的话,是从头开始覆盖式写(如只修改了前面的字符,后面字符是不会被删掉的),
# 类指针停留在写完的末尾,不是文档末尾,可以读出未被覆盖写的部分
open w+模式:
# 没有会新建junge.txt w+先写后读模式 每次都会覆盖掉原来的
f1 = open('junge.txt', 'w+', encoding='utf-8')
print(f'文件指针位置:{f1.tell()}')
f1.write('邻家有女初长成\n')
f1.write('力拔山兮气盖世\n')
print(f'文件指针位置:{f1.tell()}') # 46 14*3+\n+\n utf-8一个中文三个字符
print(f1.read()) # 读取为空 因为现在指针在46 已经是末尾了
f1.seek(0) # 把指针从新放到0
print(f1.read()) # 就可以读出来了
f1.close()
# w+:为先写后读,先写完后使用f.seek(0)回到初始位置然后开始读,
# 如果先读的话是读不出任何东西的,因为w+也是纯粹的覆盖写,
# 在未使用写操作前文档是完全空白的,无论之前该文件里有什么。
# so ,只能先写后读。
open a+模式:
# a+模式 ,没有文件会新建
f1 = open('junge.txt', 'a+', encoding='utf-8')
print(f1.tell()) # 一进来指针就在最后一位
# 要读取的话 需要把指针搞到第一位
f1.seek(0)
print(f1.read())
f1.write('天青色等烟雨') # 追加写又到末尾去了
print(f1.tell())
print(f1.read()) # 再次读取得话也记得指针
f1.close()
opne rb模式:
# a+模式 ,没有文件会报错
# 二进制格式不要指定编码:ValueError: binary mode doesn't take an encoding argument
f1 = open('junge.txt', 'rb')
readline = f1.readline()
# 加个b在字符串前面就是表示二进制格式
print(readline) # b'\xe9\x82\xbb\xe5\xae\xb6\xe6\x9c\x89\xe5\xa5\xb3\xe5\x88\x9d\xe9\x95\xbf\xe6\x88\x90\r\n'
decode = readline.decode() # 使用decode解码 邻家有女初长成
print(decode)
print(decode.encode()) # 也可以编码编回去
f1.close()
剩下的可以自己测试了
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
flush
f = open("junge.txt", "w", encoding="utf-8")
f.write("我有一瓢酒\n")
f.write("足以慰风尘\n")
f.flush()
# 当往文件写内容的时候,是内核---磁盘的交互 避免频繁交互,会有一个缓存buffer
# 相当于你打水从一楼到5楼 可以一滴一滴拿上去,也可以用桶装很多一次过去 这个桶就是缓存buffer
# buffer到了一定时间才会写入过去
# 如果这时候断电可能内容并没有写入成功,buffer里面的内容就丢失了,flush刷新会立即执行,强制把buffer
# 现在的数据写过去,不用等到特定时间
with语句
with open('junge.txt','r') as f:
print(f.read())
print(f.closed) # True
# 这样写 with 无论里面有没有异常 都会把f自动关闭了
# 有资源需要关闭的代码 建议用with
other
with open('junge.txt', 'r+', encoding='utf-8') as f:
print(f.seekable()) # 判断文件是否能移动光标
print(f.writable()) # 判断文件是否可写
print(f.readable()) # 判断文件是否可读
f.truncate() # truncate() 方法用于截断文件,如果指定了可选参数 size,
# 则表示截断文件为 size 个字符。 如果没有指定 size,则从当前位置起截断;截断之后 size 后面的所有字符被删除。