news 2026/9/10 4:58:01

Python文件操作实用指南:路径、编码、读写与实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python文件操作实用指南:路径、编码、读写与实战

写Python到现在,我遇到过不少初学者问我:“学完语法之后该练什么?”我的答案里永远有一个选项——文件操作。不是说文件操作有多难,而是它太实用了:爬虫爬下来的数据要存成文件,处理Excel表格要读写文件,程序运行的日志要记录到文件,就连配置文件也是文件。可以说,只要你的程序不是纯黑盒,早晚都要跟文件打交道。这篇文章就是一份Python文件操作的快速复习笔记,覆盖路径、编码、打开模式、读写方式、上下文管理器,再到目录操作和综合实战,适合已经学过基本语法、想系统梳理文件操作知识点的读者,也适合放在手边随时查阅。

1. 文件操作是Python里最被低估的基础功

很多人觉得文件操作不就是open()read()吗?有什么好学的。但真正写项目的时候,你会发现文件操作里藏着一堆细节:编码不对打不开、路径写错找不到文件、忘记关闭导致数据没写进去、大文件一次性读入内存直接卡死。这些问题单独拿出来都不难,但放在一起就成了新手劝退组合拳。

文件操作的基本流程其实就三步:打开文件、读写内容、关闭文件。Python内置的open()函数负责第一步和第三步的桥梁,read()write()这些方法负责第二步。举个最简单的例子:

# 读取一个文本文件 f = open('test.txt', 'r', encoding='utf-8') content = f.read() print(content) f.close()

这段代码没有任何问题,但它不是最佳写法。原因后面我会详细讲,先记住一个结论:open()出来的文件对象,用完必须关闭。不关闭的后果在Windows上特别明显——文件会被锁住,你后续想删除、重命名、覆盖它都会报权限错误。在Linux/macOS上表现没那么激烈,但反复打开不关闭,文件描述符会泄漏,程序跑久了就会报Too many open files

文件操作涉及的知识点其实是一个完整链路:路径定位到文件、指定编码解码内容、选择合适模式打开、用对方法读写、最后正确关闭。任何一个环节出问题,程序都会报错或者产生错误结果。所以我建议你把文件操作当成一个整体来学,而不是零散地记几个方法。

2. 写在open()之前:路径、编码、模式这三个基础决定了成败

open()不是魔法,它能不能成功打开文件,取决于你给它的三个参数:文件路径、打开模式、编码方式。很多人一上来就写open('test.txt'),结果报错FileNotFoundError,其实就是路径没搞对。

2.1 路径:字符串拼接不是好方案

Python里表示路径有两种方式:普通字符串和pathlib.Path对象。早期教程喜欢用字符串拼接,比如:

base_dir = '/home/user/project' data_file = base_dir + '/data/' + 'test.txt'

这种写法在Windows下会踩坑,因为Windows的路径分隔符是反斜杠\,Linux/macOS是正斜杠/。你要是直接写'C:\Users\test.txt',Python会把\U\t当成转义字符,结果路径直接错了。

从Python 3.4开始,官方推荐的方案是pathlib库,它把路径当作对象来操作,跨平台且代码可读性高:

from pathlib import Path # 构建路径 base_dir = Path('/home/user/project') data_file = base_dir / 'data' / 'test.txt' # 用 / 连接路径 # 判断是否存在 print(data_file.exists()) # 获取文件名、父目录 print(data_file.name) # test.txt print(data_file.stem) # test print(data_file.suffix) # .txt print(data_file.parent) # /home/user/project/data

Path对象有个额外好处:你不需要在代码里写死斜杠方向,pathlib会自动处理当前操作系统的路径分隔符规范。比如在Windows上,data_file的字符串表示会自动变成C:\home\user\project\data\test.txt这种反斜杠格式。

2.2 编码:UTF-8是默认选择,但Windows有坑

编码问题是Python文件操作里最容易让新手崩溃的事情。简单理解,编码就是字符和字节之间互相转换的规则。同一个“中”字,在UTF-8里占3个字节,在GBK里占2个字节,你在读取文件的时候如果用了错误的编码,要么得到乱码,要么直接报UnicodeDecodeError

Python 3的open()函数在文本模式下默认编码是locale.getpreferredencoding(),这个值在不同系统上不一样。Linux/macOS一般默认UTF-8,Windows的中文系统默认是GBK。这就是同一个脚本在Windows上报编码错误、在Linux上运行正常的原因。

我的建议很直接:写代码的时候,open()里显式指定encoding='utf-8',不要依赖默认值。如果你要处理的文件是GBK编码(比如很多Windows下生成的旧文本文件、CSV文件),那就指定encoding='gbk'。读取时不确定编码,可以用chardet库来检测,但那是另外的话题了。

# 显式指定编码,避免环境差异 with open('test.txt', 'r', encoding='utf-8') as f: content = f.read()

写入的时候同理。特别是写文件时如果忘记指定编码,Python会用默认编码去写,结果换台机器用UTF-8读取就乱码了。

2.3 模式:r、w、a、x,选错了会清空文件

open()的第二个参数是打开模式。最常用的就是下面这几个,我整理了一个表格:

模式含义文件不存在时文件存在时文件指针位置
r只读(默认)报错安全读取开头
w只写创建清空内容开头
a追加写创建保留内容末尾
x独占创建写创建报错开头
rb/wb二进制读/写r/wr/wr/w
r+读写报错安全打开开头
w+读写创建清空内容开头
a+读和追加写创建保留内容末尾

最容易出事故的是w模式。很多人想写文件,随手写了open('data.txt', 'w'),结果把原来的内容全部清空了。如果你要往已有文件里追加内容,一定要用a模式;如果你不确定文件存在且不想覆盖,用x模式最安全——文件已存在会直接报FileExistsError,不会误删数据。

还有个细节:模式字符串里加了b就表示二进制模式,此时读写的内容是bytes类型而不是str。图片、音频、视频、压缩包这些文件必须以二进制模式打开,否则会报TypeError或者数据损坏。

3. 读文件不是只会read():三种读法各有用武之地

read()是最直观的读文件方法,但不一定是最好的。选哪种读法,核心看文件大小和你要怎么处理内容。

3.1 read():小文件一口气读完

with open('small.txt', 'r', encoding='utf-8') as f: content = f.read()

read()不传参数时会把整个文件读进内存,返回一个字符串。文件小(比如几MB以内)的时候完全没问题,代码简洁、处理方便。但你得有个概念:如果文件是5GB,read()就会尝试把5GB塞进内存,结果通常是直接OOM(内存溢出)。所以我只在处理小文件时用read(),大文件绝对不用。

3.2 readline():逐行读,处理一行丢一行

with open('data.txt', 'r', encoding='utf-8') as f: line = f.readline() while line: # 处理每一行内容 print(line.strip()) line = f.readline()

readline()每次读一行,所以内存占用固定为一行的大小。上面的写法用while循环判断,当readline()读到文件末尾返回空字符串时循环结束。这个方法的缺点是代码有点啰嗦,而且如果你忘了处理行尾的换行符\n,拼接数据时容易出意外。

3.3 迭代器方式:最推荐,没有之一

上面两种写法,Python官方其实都不太推荐日常使用。因为文件对象本身就是一个迭代器,你直接用for循环遍历,代码最简洁,内存占用也最省:

with open('data.txt', 'r', encoding='utf-8') as f: for line in f: # 每读到一行就处理一行 print(line.strip())

这个写法背后就是Python在内部帮你调用readline(),每次只缓存一行数据,所以处理大文件也不怕内存爆炸。我做日志分析、爬虫数据清洗,全是这个写法,稳定又高效。

3.4 readlines():慎用,除非你知道文件不大

with open('data.txt', 'r', encoding='utf-8') as f: lines = f.readlines() # 返回每行组成的列表

readlines()把整个文件的所有行读进内存,组成一个列表。好处是你可以通过索引访问任意一行,比如lines[100]。坏处和read()一样——文件大了内存扛不住。而且如果你只是需要逐行处理,这个写法完全没必要,白白浪费内存。

文件读取时还有一个概念容易被忽略——文件指针。文件对象内部维护着一个指针,指向下一个要读的位置。read()读完全部内容后,指针在文件末尾,再调用read()返回空字符串。seek(0)可以把指针移回开头重新读,tell()可以查看当前指针位置。做断点续读、跳读时这两个方法特别有用。

4. 写文件:覆盖、追加、flush,这些细节决定了数据能不能持久化

写文件比读文件更容易踩坑,因为很多问题不会立刻暴露,等到程序崩溃你才发现数据没写进去。

4.1 write()和writelines():写入的是字符串,不是数字

with open('output.txt', 'w', encoding='utf-8') as f: f.write('hello\n') f.write('world\n')

write()一次写入一个字符串。如果你想写入的不是字符串,比如数字、列表、字典,必须先转成str或者用json序列化。直接写数字会报TypeError: write() argument must be str, not int

# 错误示范 with open('output.txt', 'w') as f: f.write(123) # TypeError # 正确示范 with open('output.txt', 'w', encoding='utf-8') as f: f.write(str(123)) # 存数字 f.write(str([1, 2, 3])) # 存列表(但存进去的是字符串表示) # 结构化存储建议用json import json data = {'name': '张三', 'age': 30} with open('data.json', 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2)

4.2 覆盖和追加:一个字符的差别,后果天壤之别

w是覆盖写入,文件原本的内容会被全部清空,从空文件开始写。a是追加写入,原有内容保留,新内容从文件末尾开始写入,不会破坏已有数据。

这个区别看起来简单,但实际项目中真的会有人写错。我之前处理一批日志,本来应该用a往旧日志里追加,结果脚本里写成了w,跑完才发现历史日志全没了。所以我自己定的规矩是:除非你确定要清空重建文件,否则一律用a模式,或者先用exists()判断一下文件状态再决定模式。

4.3 缓冲区、flush()和close():数据不是立刻落盘的

很多人以为write()之后数据马上就写到硬盘了,其实不是。Python的文件写入有缓冲区机制,write()先把数据写到内存缓冲区,等缓冲区满了、或者调用close()、或者显式调用flush(),才会真正写入硬盘。这样做的原因是减少磁盘IO频次,提升性能。

这个机制带来一个隐患:如果程序在write()之后、close()之前异常退出了,缓冲区里的数据可能还没写入硬盘,直接丢失。更常见的情况是,你往文件里写了几行日志,程序没正常结束,最后打开文件发现是空的或者少了几行。

看这个例子:

# 写完后立刻查看文件,可能啥也没有 f = open('test.txt', 'w', encoding='utf-8') f.write('hello') # 此时数据还在缓冲区 # 没有close,程序继续运行,如果你此时用别的程序打开test.txt,文件是空的 f.flush() # 强制把缓冲区数据写入硬盘 # 这下其他程序就能看到内容了 f.close()

所以有两个实用建议:

  • 写完每个逻辑块后,如果你需要立刻查看文件内容验证,调用一次flush()
  • 最好还是养成用with的习惯,让Python自动管理关闭时机(后面详细讲)。

4.4 文件编码在写场景下同样重要

写入UTF-8编码的文件时,记得在open()里指定encoding='utf-8'。跨平台运行脚本时,如果不指定编码,在Windows中文系统上写出来的文件是GBK编码,拿到Linux上用UTF-8打开就是乱码。如果你希望写出来的文件是纯ASCII内容,直接在open()里指定encoding='ascii',写入非ASCII字符时立刻报错,防止脏数据。

5. with open()是标配:上下文管理器解决90%的关闭问题

前面我反复提到with,现在系统说说为什么它是文件操作的标配写法。先看传统写法的问题:

f = open('test.txt', 'r', encoding='utf-8') content = f.read() f.close()

这段代码在正常情况下没问题。但如果f.read()抛了异常,比如文件编码不对、磁盘出错,f.close()这行就不会执行,文件句柄泄漏。文件句柄是系统资源,不释放的话,次数多了程序会崩溃。而且你还要记得在每个分支都要close(),代码稍微复杂一点就很容易漏。

with的设计就是为了解决这个问题——不管代码块正常执行完还是抛异常,它都会在退出时自动调用close()

with open('test.txt', 'r', encoding='utf-8') as f: content = f.read() # 到这里文件已经自动关闭了

很多人把这个行为叫“上下文管理器”。简单理解:with为你构建了一个安全的作用域,进入时打开资源,退出时自动释放资源。不止文件,数据库连接、网络连接、锁这些资源都可以用with管理,原理是一样的。

5.1 同时打开多个文件:一个with搞定

有时候你需要同时读写两个文件,比如把source.txt的内容复制到target.txt。可以嵌套写,也可以把多个open()写在一个with后面:

# 写法一:嵌套 with open('source.txt', 'r', encoding='utf-8') as src: with open('target.txt', 'w', encoding='utf-8') as dst: dst.write(src.read()) # 写法二:并列(Python 3.1+支持) with open('source.txt', 'r', encoding='utf-8') as src, \ open('target.txt', 'w', encoding='utf-8') as dst: dst.write(src.read())

第二种写法更简洁,两个文件都能在适当的时候自动关闭。

5.2 自定义上下文管理器:不只是文件能用

with背后的机制,就是协议——类里实现__enter__()__exit__()两个特殊方法,对象就变成了可上下文管理的资源。你也可以给自己的业务对象实现这个协议,处理“用完必须清理”的逻辑。不过在日常开发中,你更多是用现成的上下文管理器,比如pathlib.Path的对象就自带open()方法,可以和with结合使用:

from pathlib import Path p = Path('test.txt') with p.open('r', encoding='utf-8') as f: content = f.read()

效果和open('test.txt', 'r')一样,但路径处理更灵活。

6. 目录操作:从os到pathlib,遍历、筛选、批量处理一把梭

文件操作不只针对单个文件,很多时候你要处理的是一个目录下的全部文件。比如批量重命名图片、遍历项目里的所有Python文件、把多个日志合并成一个。Python里有两个方案:传统os模块和现代pathlib

6.1 列出目录内容:listdir vs iterdir

os.listdir()返回目录下所有文件和子目录的名称列表,但不包含路径信息,你得自己拼接完整路径。pathlibiterdir()则直接返回Path对象,更方便:

import os from pathlib import Path # os模块写法 files = os.listdir('.') for name in files: full_path = os.path.join('.', name) if os.path.isfile(full_path): print(full_path) # pathlib写法 p = Path('.') for item in p.iterdir(): if item.is_file(): print(item)

pathlib的路径对象直接有is_file()is_dir()suffix这些属性,省了各种判断函数,代码读起来也顺。

6.2 递归遍历目录:walk vs rglob

如果目录下面还有子目录,你需要递归遍历。os.walk()是传统方案,它会递归所有子目录,返回(当前目录路径, 子目录列表, 文件列表)三元组。pathlib则提供了更优雅的rglob()方法:

from pathlib import Path # 找出项目里所有Python文件 p = Path('/path/to/project') for py_file in p.rglob('*.py'): print(py_file)

rglob('*.py')会递归匹配所有.py文件,返回Path对象生成器。这个需求以前用os.walk()要写好几行,现在一行搞定。

6.3 批量重命名:一个实战示例

目录操作最常见的场景是批量重命名。假设你在整理照片,想把IMG_001.jpg这种命名改成2024-01-01_001.jpg这种格式。用pathlib可以这样写:

from pathlib import Path photo_dir = Path('/path/to/photos') for img in photo_dir.glob('IMG_*.jpg'): # 把旧前缀替换成日期前缀 new_name = f"2024-01-01_{img.stem.split('_')[1]}.jpg" img.rename(photo_dir / new_name) print(f"已重命名: {img.name} -> {new_name}")

这个例子说明了一个关键点:直接用pathlibrename()方法,参数是目标路径的Path对象,比os.rename()需要手动拼接字符串更不容易出错。

6.4 glob模式匹配:文件筛选利器

pathlibglob()rglob()都支持通配符匹配:*匹配任意字符串,?匹配单个字符,还可以用[abc]匹配字符集合。这在筛选文件时特别好用:

from pathlib import Path p = Path('/tmp/data') # 所有以 .log 结尾的文件 logs = list(p.glob('*.log')) # 所有以 access_log 开头、以 .txt 结尾的文件 access_txt = list(p.glob('access_log_*.txt')) # 2023年或2024年的数据文件 data_23_24 = list(p.glob('data_202[34]_*.csv'))

7. 文件操作避坑指南:这几个坑我踩过之后才彻底明白

这一节我总结几个自己实际踩过的坑,每个都真实发生过,写出来帮你少走点弯路。

7.1 写入后立刻读取,读到的是空内容

场景:我写一个数据处理脚本,先向文件写入结果,然后立刻用另一个函数读取这个文件,结果读到空字符串。排查了半天发现是缓冲区问题——写入的数据还在缓冲区,没有落盘,读取的时候自然啥也读不到。

解决方案:写入完成后调用flush(),或者用with把写入操作完整结束后再读取。如果你要在同一个进程里先写后读,也可以考虑用r+模式打开文件,或者写完后重新open()读取。

7.2 文件编码报错:UnicodeDecodeError

场景:在Windows上生成的一个CSV文件,用我Linux开发环境上的Python脚本读取,直接报UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 0

解决方案:这个错误就是编码不匹配。我先用chardet探测大概编码,发现是GBK:

import chardet with open('data.csv', 'rb') as f: raw = f.read(10000) # 读取前1万字节来检测 result = chardet.detect(raw) print(result) # {'encoding': 'GB2312', 'confidence': 0.99}

然后指定正确编码读取:

with open('data.csv', 'r', encoding='gbk') as f: content = f.read()

后来我在写脚本时,凡是需要处理来源不固定的文本文件,都会在前面加入编码探测逻辑,避免这个问题。

7.3 路径里带空格或者中文字符,导致找不到文件

场景:一个用户上传的文件路径是C:\Users\张三\My Documents\新建文件夹\report.txt,脚本里用字符串拼接路径,结果报错说找不到文件。

解决方案:这个问题通常是路径拼接不正确导致的,比如用了+拼接而漏掉了分隔符,或者转义字符没有被正确处理。使用pathlib/运算符可以有效规避这个问题:

from pathlib import Path base = Path('C:/Users/张三') file_path = base / 'My Documents' / '新建文件夹' / 'report.txt'

注意即使路径包含空格、中文字符,Path对象也能正确处理,不需要手动转义。

7.4 大文件读取导致内存不足

场景:处理一个8GB的日志文件,直接用read(),程序跑了十几分钟后内存爆掉,进程被系统杀掉。

解决方案:换成迭代器逐行读取,内存占用从GB级别降到几MB:

with open('huge.log', 'r', encoding='utf-8') as f: for line in f: process_line(line)

如果需要处理超大文件的某个特定部分,可以用seek()定位到指定偏移量再读,避免从头遍历。

7.5 文件操作抛出PermissionError

场景:在Windows上运行脚本读取一个Excel文件,报PermissionError: [Errno 13] Permission denied。原因就是那个文件正被另一个程序(比如Excel)独占打开,Python没办法同时读取。

解决方案:先关闭占用文件的程序再运行脚本。另外,如果脚本本身之前打开过文件但没关闭,也会导致后续操作失败。用with管理文件对象能从根上避免这个问题。

8. 实战:按日期拆分日志文件的完整脚本

理论聊得差不多了,来一个综合实战。假设你有一个大日志文件app.log,里面的内容按行记录,每行以日期开头:

2024-01-01 10:23:45 INFO 用户登录 2024-01-01 10:25:12 DEBUG 数据库写入成功 2024-01-02 09:31:08 ERROR 连接超时 2024-01-02 11:02:55 INFO 任务完成 2024-01-03 08:15:33 WARNING 磁盘空间不足

需求是把这个大文件按日期拆分成多个小文件:log_2024-01-01.txtlog_2024-01-02.txt,以此类推。用文件操作的知识,我们可以这样实现:

from pathlib import Path def split_log_by_day(log_path): log_file = Path(log_path) if not log_file.exists(): print(f"日志文件不存在: {log_file}") return current_date = None output_file = None try: with log_file.open('r', encoding='utf-8') as f: for line in f: # 假设每行前10个字符是日期 YYYY-MM-DD date_str = line[:10].strip() if not date_str: continue # 日期发生变化时,切换输出文件 if date_str != current_date: # 关闭之前的输出文件 if output_file: output_file.close() current_date = date_str output_filename = Path(f"log_{date_str}.txt") # 使用追加模式,防止重复运行时覆盖已有内容 output_file = output_filename.open('a', encoding='utf-8') # 写入当前行 output_file.write(line) finally: # 确保最后一个输出文件也关闭了 if output_file: output_file.close() if __name__ == '__main__': split_log_by_day('app.log')

这个脚本有几个值得注意的设计点:

  • pathlib处理路径,避免字符串拼接和平台差异问题。
  • 用迭代器方式逐行读取大日志,内存开销小,日志文件几个GB也能处理。
  • 日期变化时关闭上一个文件、打开新文件,注意文件关闭时机。
  • 输出文件用追加模式a而不是覆盖模式w,这样即使脚本重复运行,也不会丢失之前拆出来的内容。
  • try/finally确保所有打开的文件最终都能关闭。

跑完这个脚本,原本一个大文件就变成了按日期划分的多个小文件,后续按日期分析日志就方便多了。同样的思路可以扩展到按小时拆分、按IP拆分、按错误级别拆分,核心逻辑都是“逐行读取 + 按条件切换输出文件”。

如果你想把多个小日志合并成一个大文件,反向操作也很简单:

from pathlib import Path def merge_logs(output_path, log_files): with Path(output_path).open('w', encoding='utf-8') as out: for log_file in log_files: with Path(log_file).open('r', encoding='utf-8') as inf: for line in inf: out.write(line) # 用法 merge_logs('merged.log', ['log_2024-01-01.txt', 'log_2024-01-02.txt'])

9. 文件操作进阶方向:JSON序列化、CSV处理、临时文件

到这里,基础的文件读写已经覆盖完了。但实际开发里,你常常不是直接读写纯文本,而是读写特定格式的数据。我简单提几个高频场景,作为进阶方向。

9.1 JSON文件的读写:项目配置、API响应的标准格式

JSON是Python程序之间、前后端之间交换数据最常用的格式。json模块配合文件操作,两行代码就能搞定:

import json from pathlib import Path # 写入JSON data = { "name": "文件操作复习", "tags": ["python", "文件", "复习"], "version": 1.0 } with Path('config.json').open('w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=2) # 读取JSON with Path('config.json').open('r', encoding='utf-8') as f: loaded = json.load(f) print(loaded["name"]) # 文件操作复习

几个注意点:ensure_ascii=False保证中文正常显示而不是变成\uXXXXindent=2让JSON有缩进,方便人阅读;读取时如果JSON格式不对会抛JSONDecodeError,建议用try/except包裹。

9.2 CSV处理:数据分析和脚本自动化绕不开的格式

CSV可以用csv模块处理,比手动按逗号拆分靠谱得多,因为CSV字段里可能包含逗号、引号、换行,只有专用模块能正确解析:

import csv from pathlib import Path # 写入CSV with Path('data.csv').open('w', encoding='utf-8', newline='') as f: writer = csv.writer(f) writer.writerow(['日期', '访问量', '来源']) writer.writerow(['2024-01-01', '1024', '搜索引擎']) # 读取CSV with Path('data.csv').open('r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: print(row['日期'], row['访问量'])

注意写入CSV时newline=''这个参数,如果省略,在Windows上可能每行之间多一个空行。

9.3 临时文件:程序运行过程中的存储

如果你需要一个临时文件存放中间结果,跑完自动删除,可以用tempfile模块:

import tempfile from pathlib import Path with tempfile.NamedTemporaryFile(prefix='myapp_', suffix='.tmp', delete=True) as temp: temp_path = Path(temp.name) temp.write(b'temporary data') # 在临时文件上做操作 print(f"临时文件位置: {temp_path}") # 离开with后临时文件自动删除

这在处理超大文件、需要临时存储中间结果的场景下特别实用。比如你从网络下载一个大文件,先存到临时文件,校验完成后再移动到正式目录,避免下载一半的文件污染正式目录。

9.4 二进制文件:读写图片、音频、压缩包

前面提到,处理非文本文件必须使用二进制模式。比如复制一张图片:

from pathlib import Path def copy_binary(src_path, dst_path): src = Path(src_path) dst = Path(dst_path) # 分块复制,避免大文件占满内存 with src.open('rb') as src_file, dst.open('wb') as dst_file: while chunk := src_file.read(8192): # 每次读8KB dst_file.write(chunk) copy_binary('photo.jpg', 'photo_copy.jpg')

这个例子里用到了海象表达式:=和分块读取,二进制文件不管多大都不会撑爆内存。如果你只是简单复制文件,直接shutil.copy()更省事,但理解分块读写的原理对以后开发大文件处理工具很有帮助。

文件操作这块内容,学起来不难,但真正做到不出错、性能好,需要在实际项目里反复打磨。我见过很多人在项目里写文件操作,代码能跑,但一遇到异常就崩、一处理大文件就卡、一跨平台就乱码。能把路径、编码、模式、生命周期管理这几个点想清楚,文件操作这块基本就稳了。

我个人在写文件处理代码时的习惯是:路径统一用pathlib,打开文件统一用with open(),编码统一显式指定utf-8,大文件统一用迭代器逐行或分块处理。这几个习惯帮我规避掉了绝大部分文件操作相关的生产事故。如果你还没有自己的固定写法,建议从今天开始把这套流程内化成肌肉记忆。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 4:57:58

智能体系统架构三原则:隔离、集成与治理实战指南

1. 这不是又一个“架构图PPT”,而是一套能落地的智能体系统建造手册“智能体系统架构:隔离、集成与治理的综合调研”——看到这个标题,很多同行第一反应是:哦,又是那种画几个方框、连几条箭头、标上“Agent”“Orchest…

作者头像 李华
网站建设 2026/9/10 4:56:25

CANN/ge DataFlow map_input函数文档

# map_input 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、T…

作者头像 李华
网站建设 2026/9/10 4:53:34

CANN/ge内存约束设计文档

GE Memory Constraints Document 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyT…

作者头像 李华
网站建设 2026/9/10 4:52:57

RAKE接收机MATLAB仿真:多径分集与MRC合并实现

简介:本资源是一套面向通信工程专业学生与初学者的RAKE接收机MATLAB仿真程序,聚焦CDMA系统中多径衰落信号的接收与合并问题,帮助理解扩频通信核心机制及Rake结构设计原理。压缩包共9个文件,含8个.m脚本(如rake_receive…

作者头像 李华
网站建设 2026/9/10 4:51:20

LabVIEW阶次分析实战:从等角度重采样到旋转机械故障诊断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 4:51:13

跨境电商短视频七种爆款脚本结构,从开箱到转化全拆解

1. 为什么你拍了一百条开箱视频,店铺还是没起色先聊个现象。我见过不少做跨境电商的卖家,尤其是刚起步那阵子,最顺手的就是拍开箱——产品到了,拆开,逐个展示,讲两句使用感受,配上热门BGM发出去…

作者头像 李华