一、os 模块(操作系统相关操作)
1. 基础信息获取
os.name
:返回操作系统标识nt
:代表 Windows 系统posix
:代表 Unix/Linux 系统
os.curdir
:返回当前目录符号(.
)os.environ
:获取系统环境变量(如os.environ["PATH"]
查看 PATH 变量)os.chdir(path)
:切换当前工作目录
2. 目录操作(创建 / 删除)
函数 | 功能 | 注意事项 |
---|---|---|
os.mkdir(path) |
创建单个目录 | 父目录必须存在;目录已存在则报错 |
os.makedirs(path) |
递归创建目录(含不存在的父目录) | 目标目录已存在则报错 |
os.rmdir(path) |
删除空目录 | 目录非空则报错 |
os.removedirs(path) |
递归删除路径中所有空目录(从子到父,遇到非空目录则停止) | |
os.listdir(path) |
获取指定路径下的所有文件 / 目录名称,返回列表 |
3. 路径分隔符处理
- Windows 用
\
,Linux 用/
- 表示路径时避免转义问题:
- 加
r
前缀(如r"D:\test"
) - 用
\\
替代\
(如"D:\\test"
) - 统一用
/
(跨平台兼容,如"D:/test"
)
- 加
二、os.path 模块(路径处理)
1. 路径判断
os.path.exists(path)
:判断路径是否存在os.path.isfile(path)
:判断路径是否为文件os.path.isdir(path)
:判断路径是否为目录os.path.isabs(path)
:判断是否为绝对路径
2. 路径解析
os.path.dirname(path)
:获取父级路径(如"D:/abc/1.txt"
返回"D:/abc"
)os.path.basename(path)
:获取文件名 / 目录名(如"D:/abc/1.txt"
返回"1.txt"
)os.path.join(parent, name)
:拼接路径- 若
name
是绝对路径,则直接返回name
(忽略parent
)
- 若
3. 路径转换与信息
os.path.abspath(path)
:获取绝对路径os.path.getsize(path)
:获取文件大小(字节),目录默认返回 4096- 时间相关(返回时间戳,需用
datetime.fromtimestamp()
转换):os.path.getctime(path)
:创建时间os.path.getatime(path)
:最后访问时间os.path.getmtime(path)
:最后修改时间
三、文件操作
1. 文件类型
- 字符文件 :存储文本内容(如
.txt
,可用记事本打开) - 字节文件 :二进制文件(如
.png
、.exe
)
2. open () 函数(核心)
用于打开文件,返回文件对象,语法:
open(path, mode, encoding)
path
:文件路径(不可指向目录)mode
:操作模式(默认rt
):- 读写模式:
r
(读)、w
(写,覆盖)、a
(追加)、x
(创建新文件,存在则报错)、+
(读写) - 数据类型:
t
(文本模式,字符串,需指定encoding
)、b
(字节模式,二进制流,不指定encoding
)
- 读写模式:
- 推荐用
with
语句自动关闭文件:with open(...) as f: ...
3. 读取方法(文件对象方法)
方法 | 功能 | 适用场景 |
---|---|---|
f.read(n) |
读取n 个字符 / 字节,默认读全部 |
小文件 |
f.readline() |
读取一行数据 | 按行读取 |
f.readlines() |
读取所有行,返回列表(每行作为元素) | 行数较少的文件 |
f.seek(n) |
将读取光标移到第n 个字符 / 字节处 |
随机读取 |
4. 写入方法(文件对象方法)
方法 | 功能 | 说明 |
---|---|---|
f.write(content) |
写入内容(文本模式传字符串,字节模式传b"..." ) |
|
f.writelines(list) |
批量写入列表中的元素(需自行加换行符) |
5. 大文件处理
避免一次性读取全部内容(内存溢出),循环分块读取:
# 大字符文件
with open("large.txt", "rt", encoding="utf-8") as f:
while (data := f.read(1000)) != "": # 每次读1000字符
print(data)
# 大字节文件
with open("large.png", "rb") as f:
while (data := f.read(8 << 10)) != b"": # 每次读8KB
print(data)
四、目录高级操作(自定义函数)
1. 递归获取目录下所有文件
def get_files(direction):
"""返回目录下所有文件的绝对路径(含子目录)"""
ret = []
for file in os.listdir(direction):
file_path = os.path.join(direction, file)
if os.path.isfile(file_path):
ret.append(file_path)
else:
ret += get_files(file_path) # 递归子目录
return ret
2. 递归删除目录(含内容)
def remove_dir(direction):
"""删除目录及所有子文件/子目录"""
for file in os.listdir(direction):
path = os.path.join(direction, file)
if os.path.isfile(path):
os.remove(path) # 删除文件
else:
remove_dir(path) # 递归删除子目录
os.rmdir(direction) # 最后删除空目录
五、shutil 模块(高级文件 / 目录操作)
函数 | 功能 | 注意事项 |
---|---|---|
shutil.copyfile(src, dst) |
拷贝文件内容(仅文件) | dst 若存在则覆盖 |
shutil.copy(src, dst) |
拷贝文件(含权限),dst 可为目录(自动用原文件名) |
|
shutil.move(src, dst) |
移动 / 重命名文件 / 目录 | - 移动到目录:dst 必须存在 - 重命名:dst 需不存在 |
shutil.copytree(src, dst) |
递归拷贝目录(含所有内容) | dst 必须不存在 |
shutil.rmtree(src) |
递归删除目录及所有内容(危险!) | 无需目录为空 |
六、绝对路径表示
- Windows:
D:/abc
或D:\abc
(推荐用/
跨平台) - Linux:
/abc
一、文件工具类 FileUtils
封装了文件 / 目录的常用操作,提供一系列类方法处理路径、文件读写、拷贝、删除等功能。
from typing import List, Callable
import os
class FileUtils:
@classmethod
def get_files(cls, path: str, predicate: Callable[[str], bool] = None) -> List[str]:
"""根据条件获取指定目录下所有满足条件的文件(非递归,仅当前目录)"""
data = os.listdir(path)
ret = []
for item in data:
file = os.path.join(path, item)
if predicate(file): # 满足条件的文件路径加入结果
ret.append(file)
return ret
@classmethod
def remove(cls, path: str) -> None:
"""递归删除文件或目录(支持非空目录)"""
if os.path.isdir(path):
# 先删除目录内所有内容
for item in os.listdir(path):
item_path = os.path.join(path, item)
cls.remove(item_path)
os.rmdir(path) # 最后删除空目录
else:
os.remove(path) # 直接删除文件
@classmethod
def get_parent(cls, path: str) -> str:
"""获取路径的父级目录"""
return os.path.dirname(path)
@classmethod
def get_name(cls, path: str) -> str:
"""获取路径中的文件名或目录名"""
return os.path.basename(path)
@classmethod
def get_size(cls, file: str) -> int:
"""获取文件大小(字节),目录默认返回4096"""
return os.path.getsize(file)
@classmethod
def is_dir(cls, path: str) -> bool:
"""判断路径是否为目录"""
return os.path.isdir(path)
@classmethod
def is_file(cls, path: str) -> bool:
"""判断路径是否为文件"""
return os.path.isfile(path)
@classmethod
def exists(cls, path: str) -> bool:
"""判断路径是否存在"""
return os.path.exists(path)
@classmethod
def get_ext(cls, file: str) -> str:
"""获取文件后缀名(不含.),无后缀返回空字符串"""
ext = os.path.splitext(file)[1]
return ext[1:] if ext else '' # 去除前缀.
@classmethod
def copy_file_to_dir(cls, file: str, directory: str) -> None:
"""将文件拷贝到目标目录(保留原文件名)"""
dest_path = os.path.join(directory, cls.get_name(file))
cls.copy_file(file, dest_path)
@classmethod
def copy_file(cls, srcfile: str, destfile: str) -> None:
"""拷贝源文件内容到目标文件(二进制方式,支持所有文件类型)"""
with open(srcfile, 'rb') as f, open(destfile, 'wb') as w:
while (data := f.read(8 << 10)) != b'': # 每次读8KB
w.write(data)
@classmethod
def copy_directory(cls, src: str, dest: str) -> None:
"""递归拷贝目录(含所有子文件和子目录)"""
# 遍历源目录内容
for item in os.listdir(src):
src_path = os.path.join(src, item)
dest_path = os.path.join(dest, item)
if os.path.isfile(src_path):
cls.copy_file(src_path, dest_path) # 拷贝文件
else:
# 若目标子目录不存在则创建,递归拷贝
if not os.path.exists(dest_path):
os.makedirs(dest_path)
cls.copy_directory(src_path, dest_path)
@classmethod
def read_to_string(cls, file: str, encoding="utf-8") -> str:
"""读取文本文件内容并返回字符串"""
with open(file, 'rt', encoding=encoding) as f:
return f.read()
@classmethod
def chunks(cls, file: str, chunk_size: int = 8192):
"""生成器:分块读取大文件(字节方式),默认每次8KB"""
with open(file, 'rb') as f:
while True:
data = f.read(chunk_size)
if not data: # 读取完毕
break
yield data
@classmethod
def writestr(cls, string: str, file: str, encoding="utf-8") -> None:
"""追加字符串到文本文件(若文件不存在则创建)"""
with open(file, 'a', encoding=encoding) as f:
f.write(string)
二、递归函数(文件 / 目录操作)
1. 递归获取所有文件路径
python
运行
def list_files(path: str) -> List[str]:
"""递归获取指定目录下所有文件的绝对路径(含所有子目录)"""
result = []
for item in os.listdir(path):
item_path = os.path.join(path, item)
if os.path.isfile(item_path):
result.append(item_path) # 是文件则直接加入
else:
result += list_files(item_path) # 是目录则递归
return result
2. 递归删除目录(不依赖 shutil)
def remove_dir(path: str) -> None:
"""递归删除目录及所有内容(不使用shutil模块)"""
# 先删除目录内所有子项
for item in os.listdir(path):
item_path = os.path.join(path, item)
if os.path.isdir(item_path):
remove_dir(item_path) # 递归删除子目录
else:
os.remove(item_path) # 删除文件
os.rmdir(path) # 最后删除空目录
三、文件描述符抽象类及实现
基于抽象基类定义文件读取接口,分别实现文本文件和字节文件的读取。
from abc import ABC, abstractmethod
class InFileDescriptor(ABC):
"""文件读取抽象基类,定义基本接口"""
def __init__(self, path=None):
self._path = path # 路径属性
self._file = None # 文件对象(子类初始化)
@abstractmethod
def read(self, n=1):
"""抽象方法:读取指定长度数据"""
pass
@abstractmethod
def readall(self):
"""抽象方法:读取所有数据"""
pass
def chunks(self, chunk_size=8192):
"""生成器:分块读取数据(默认8KB)"""
while True:
data = self._file.read(chunk_size)
if not data: # 读取完毕
break
yield data
@abstractmethod
def close(self):
"""抽象方法:关闭文件流"""
pass
class FileInput(InFileDescriptor):
"""文本文件读取类(字符模式)"""
def __init__(self, path, *, encoding="UTF-8"):
super().__init__(path)
self._encoding = encoding # 编码方式
self._file = open(self._path, 'rt', encoding=encoding) # 文本模式打开
def read(self, n=1):
"""读取n个字符(默认1个)"""
return self._file.read(n)
def readline(self):
"""读取一行内容"""
return self._file.readline()
def readlines(self):
"""读取所有行,返回列表"""
return self._file.readlines()
def readall(self):
"""读取所有内容,返回字符串"""
return self._file.read()
def close(self):
"""关闭文件流"""
self._file.close()
class FileInputStream(InFileDescriptor):
"""字节文件读取类(二进制模式)"""
def __init__(self, path):
super().__init__(path)
self._file = open(self._path, 'rb') # 二进制模式打开
def read(self, n=1):
"""读取n个字节(默认1个)"""
return self._file.read(n)
def readall(self):
"""读取所有内容,返回字节串"""
return self._file.read()
def close(self):
"""关闭文件流"""
self._file.close()
四、测试代码说明(原注释部分)
包含对FileUtils
类的功能测试,主要流程:
- 创建测试目录和文件并写入内容
- 验证文件 / 目录存在性、大小、名称等属性
- 读取文件内容、筛选特定类型文件
- 测试文件和目录拷贝功能
- 测试删除功能及清理操作