Skip to main content

第四课:文件操作

(一)文件管理

1. 文件路径处理

从文件地址中提取出文件名

import os
input_audio_path =r"""C:\Users\白山\Desktop\coding learning\音频调节器开发\歌曲测试源\测试歌曲.mp3"""
file_name = os.path.basename(input_audio_path)   
file_name=file_name.split(".")
file_name[1]="wav"
file_name='.'.join(file_name)
print(file_name)

路径整合

directory = "test_folder/subfolder"
filename =  "example.txt"
file_path = os.path.join(directory, filename)
print(file_path)

2. 文件基本操作

创建

  • os.makedirs(directory, exist_ok=True) 可确保目录路径存在。

  • 'w' 模式创建新文件,如文件已存在会清空原内容。

import os

def create_file(directory, filename, content=""):
    os.makedirs(directory, exist_ok=True)  # 确保目录存在
    file_path = os.path.join(directory, filename)
    
    with open(file_path, 'w', encoding='utf-8') as f:
        f.write(content)  # 可以写入初始内容
    print(f"文件已创建: {file_path}")

# 示例
create_file("test_folder/subfolder", "example.txt", "初始内容")

重命名

os.rename("old_file.txt", "new_file.txt")
print("文件名已修改")

移动

  • 如果目标是文件夹,则文件移动到该目录;如果目标是新文件名,则文件会被重命名。
shutil.move("file.txt", "new_location/")
print("文件已移动")

复制

import shutil

shutil.copy("source.txt", "destination.txt")  # 复制文件
shutil.copy("source.txt", "backup_folder/")   # 复制到目录
print("文件已复制")

删除

import os

file_path = "test.txt"
if os.path.exists(file_path):  # 先检查文件是否存在
    os.remove(file_path)
    print(f"{file_path} 已删除")
else:
    print(f"{file_path} 不存在")

3. 文件夹基本操作

创建

os.mkdir("new_folder")
print("文件夹已创建")

os.makedirs("parent_folder/sub_folder", exist_ok=True)
print("多级文件夹已创建")

重命名

os.rename("old_folder", "new_folder")
print("文件夹名已修改")

移动

目标目录路径可以是:

  • 新目录名称(文件夹重命名 + 移动)
  • 现有目录路径(只是换个位置)
import shutil
import os

def move_folder(src_folder, dst_folder):
    # 如果目标目录不存在,则创建
    os.makedirs(os.path.dirname(dst_folder), exist_ok=True)
    shutil.move(src_folder, dst_folder)
    print(f"文件夹从 {src_folder} 移动到了 {dst_folder}")

# 示例
move_folder("test_folder/subfolder", "moved_folder/subfolder")

复制

shutil.copytree("source_folder", "destination_folder")
print("文件夹已复制")

删除

folder_path = "empty_folder"
if os.path.exists(folder_path):  # 先检查文件夹是否存在
    os.rmdir(folder_path)  # 只能删除空文件夹
    print(f"{folder_path} 已删除")
else:
    print(f"{folder_path} 不存在")
  • 如果文件夹 非空,使用 shutil.rmtree(path)
import shutil
shutil.rmtree("non_empty_folder")
print("非空文件夹已删除")

4. 目录扫描

扫描指定路径下的所有文件和文件夹,并返回两个 list

def scan_directory(path):
    files = []
    folders = []
    
    for item in os.listdir(path):
        full_path = os.path.join(path, item)
        if os.path.isfile(full_path):
            files.append(item)
        elif os.path.isdir(full_path):
            folders.append(item)
    
    return files, folders

# 示例
path = "./test_folder"
files, folders = scan_directory(path)
print("文件:", files)
print("文件夹:", folders)

递归扫描指定路径下的所有文件和文件夹,并返回字典(文件名对应 None

import os

def recursive_scan(path):
    result = {}
    
    # 获取当前目录下的所有内容
    for item in os.listdir(path):
        full_path = os.path.join(path, item)
        
        if os.path.isdir(full_path):
            # 文件夹:递归构建其内容
            result[item] = recursive_scan(full_path)
        else:
            # 文件:对应值为 None
            result[item] = None
    
    return result

# 示例
path = "./test_folder"
directory_structure = recursive_scan(path)
print(directory_structure)

假设目录结构如下

test_folder/
├── file1.txt
├── subfolder1/
│   ├── file2.txt
│   └── inner/
│       └── file3.txt
├── subfolder2/

返回的字典结构如下:

{
    'file1.txt': None,
    'subfolder1': {
        'file2.txt': None,
        'inner': {
            'file3.txt': None
        }
    },
    'subfolder2': {}
}


(二)TXT 文件读写

1. 读取文件

python常用的读取文件函数有三种read()、readline()、readlines()

  • read() 一次性读全部内容,以字符串的形式返回结果
  • readline() 只读取文本第一行的内容,以字符串的形式返回结果
  • readlines() 读取文本所有内容,并且以数列的格式返回结果,一般配合for in使用
with open("test.txt", "r") as f:  # 打开文件
    data = f.read()  # 读取文件
    print(data)
    
with open("test.txt", "r") as f:
    data = f.readline()
    print(data)
    
with open("test.txt", "r") as f:
    for line in f.readlines():
        line = line.strip('\n')  #去掉列表中每一个元素的换行符
        print(line)

逐行读取文件的简写

path=r"C:\Users\白山\Desktop\coding learning\test.txt"
for i in open(path):  #read() 方法用于一次性读取整个文件的内容
  print(i)    #直接for循环加open就可以实现逐行读取

安全地读取文件

try:  #try 块是包含可能会引发异常的代码块
    f = open('致橡树.txt', 'r', encoding='utf-8')
    print(f.read())
except FileNotFoundError:  #except 块用于捕获并处理可能在 try 块中引发的异常
    print('无法打开指定的文件!')
except LookupError:
    print('指定了未知的编码!')
except UnicodeDecodeError:
    print('读取文件时解码错误!')
finally:    #finally 块中的代码始终会被执行,无论是否发生异常
    if f:
        f.close()

with 语句用于创建一个上下文管理器,它可以自动管理资源的分配和释放,

with 语句的作用是打开文件并确保在块执行完成后正确关闭文件,无论是否发生异常。

def main():
    try:
        with open('致橡树.txt', 'r', encoding='utf-8') as f:  #这种open as f 的格式只用于with
            print(f.read())  #注意缩进
    except FileNotFoundError:
        print('无法打开指定的文件!')
    #这里就不需要finally了

with 语句的作用是在进入上下文时调用上下文管理器的 enter 方法,并在离开上下文时调用 exit 方法。这可用于确保在离开上下文时资源被正确释放


逐行读取

with open('致橡树.txt', mode='r') as f:
        for line in f:
            print(line, end='')  #同一行输出,用空格隔开
with open('致橡树.txt') as f:
        lines = f.readlines()

2. 写入文件

with open("test.txt","w") as f:
    f.write("这是个测试!")  # 自带文件关闭功能,不需要再写f.close()

有几种open的方法

模式描述
r读取文件,若文件不存在则报错
w写入文件,若文件不存在先创建会覆盖原文件
a写入文件,若文件不存在先创建不会覆盖原文件,而是追加在末尾
rb以二进制方式读取,若文件不存在则报错
wb以二进制方式写入,若文件不存在先创建会覆盖原文件
r+可读可写,文件必须存在,否则报错,写操作会覆盖部分内容
w+可读可写,若文件不存在先创建会覆盖原文件
a+可读可写,若文件不存在先创建不会覆盖,追加在末尾

3. 清空文件

with open(r'test.txt','a+',encoding='utf-8') as test:
    test.truncate(0)

(三)Word 文件读写

(四)Excel 文件读写

1. exel的写入

import datetime
from openpyxl import Workbook
wb = Workbook()   #创建一个新的 Excel 工作簿对象,该工作簿包含一个默认的工作表(工作表名称为 "Sheet")
ws = wb.active   #获取工作簿中的活动工作表(默认的 "Sheet" 工作表)对象,以便后续向其中写入数据。
ws['A1'] = 42
ws.append([1, 2, 3])     #列表 [1, 2, 3] 写入工作表的下一行(自动追加到最后一行)。
ws['A2'] = datetime.datetime.now()   #会把之前写好的1覆盖掉
wb.save("sample2.xlsx")

如果要自己创建工作表,可修改成如下

wb = Workbook()  # 创建一个新的 Excel 工作簿对象
wb.remove(wb.active)  # 移除默认创建的工作表 "Sheet"
ws = wb.create_sheet("A")  # 创建一个名为 "A" 的新工作表

2. excel的修改

from openpyxl import load_workbook
workbook = load_workbook('sample2.xlsx')   # 打开已存在的 Excel 文件
# worksheet = workbook['Sheet1']   # 获取工作表对象(假设工作表名为 'Sheet1')
worksheet = workbook.active
worksheet['A1'] = 'New Value'  # 修改单元格 A1 的值为 'New Value'
worksheet['B2'] = 42            # 修改单元格 B2 的值为 42
workbook.save('existing_file.xlsx')  # 保存修改后的 Excel 文件
workbook.close()   # 关闭 Excel 文件

(五)CSV 文件读写

注意csv和excel是完全不一样的!CSV可以直接用记事本打开,excel不行!用的库也不一样!

1. CSV的写入

列表写入

import csv
data = [
    ['Name', 'Age', 'City'],
    ['Alice', 28, 'New York'],
    ['Bob', 22, 'Los Angeles'],
    ['Charlie', 30, 'Chicago']
]
with open('output.csv', 'w', newline='', encoding='utf-8') as file:   #newline='' 用于防止在行间产生额外的空行。
    writer = csv.writer(file)
    for row in data:
        writer.writerow(row)

字典写入

data = [
    {'Name': 'Alice', 'Age': 28, 'City': 'New York'},
    {'Name': 'Bob', 'Age': 22, 'City': 'Los Angeles'},
    {'Name': 'Charlie', 'Age': 30, 'City': 'Chicago'}
]
with open('output.csv', 'w', newline='', encoding='utf-8') as file:
    fields = ['Name', 'Age', 'City']
    writer = csv.DictWriter(file, fieldnames=fields)
    writer.writeheader()  # 写入列名
    for row in data:
        writer.writerow(row)

(五)图片读写

1. 打开图像和图像信息

from PIL import Image
image=Image.open(r"C:\Users\白山\Desktop\coding learning\2.png")
print(image.format)   #文件格式,例如JPEG、PNG等           PNG
print(image.size)     #图像的尺寸                          (1003, 966)        
print(image.mode)     #颜色模式,例如 "RGB" 表示真彩色图像   RGBA(加上了透明度)
image.show()          #展示图片

2. 剪裁图片

from PIL import Image
image=Image.open(r"C:\Users\白山\Desktop\coding learning\2.png")
rect = 80, 20, 310, 360       #左上角的坐标为 (80, 20),右下角的坐标为 (310, 360)
image.crop(rect).show()       #不会改变原图
image.crop(rect).save("cropped_image.png")     #保存改好的图片

3. 生成缩略图

from PIL import Image
image=Image.open(r"C:\Users\白山\Desktop\coding learning\2.png")
size = 128, 128
image.thumbnail(size)
image.show()       #不会改变原图,此show不能和thumbnail连用

4. 缩放和粘贴图像

from PIL import Image
image1 = Image.open(r"C:\Users\白山\Desktop\coding learning\1.png")
image2 = Image.open(r"C:\Users\白山\Desktop\coding learning\2.png")
rect = 80, 20, 310, 360
guido_head = image2.crop(rect)
width, height = guido_head.size
image1.paste(guido_head.resize((int(width / 1.5), int(height / 1.5))), (172, 40))
image1.show()

5. 翻转和翻转

from PIL import Image
image=Image.open(r"C:\Users\白山\Desktop\coding learning\2.png")
image.rotate(180).show()
image.transpose(Image.FLIP_LEFT_RIGHT).show()   #左右翻转
image.transpose(Image.FLIP_TOP_BOTTOM).show()   #上下翻转

6. 操作像素

from PIL import Image
image = Image.open(r"C:\Users\白山\Desktop\coding learning\2.png")
for x in range(80, 310):
   for y in range(20, 360):
        image.putpixel((x, y), (128, 128, 128))  #在这个区间的像素内填入灰色
image.show()

7. 滤镜

from PIL import Image, ImageFilter
image = Image.open(r"C:\Users\白山\Desktop\coding learning\2.png")
image.filter(ImageFilter.EDGE_ENHANCE).show()
  • ImageFilter.BLUR: 对图像进行模糊处理。
  • ImageFilter.SHARPEN: 对图像进行锐化处理。
  • ImageFilter.EDGE_ENHANCE: 增强图像的边缘。
  • ImageFilter.EMBOSS: 使图像具有浮雕效果。
  • ImageFilter.CONTOUR: 产生图像轮廓线条。
  • ImageFilter.DETAIL: 增强图像的细节。