python手把手50天就业(八) 文件操作

工程师们大家好,配套免费视频(平时上班周末录制)

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 后面的所有字符被删除。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说重点丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值