使用Python进行文件读写的API或方法及其注意事项

张开发
2026/4/21 19:19:52 15 分钟阅读

分享文章

使用Python进行文件读写的API或方法及其注意事项
本文总结了Python文件读写的核心API及注意事项。主要内容包括1文件打开与关闭方法推荐使用with语句自动管理资源2文件读取方法如read()、readline()等注意大文件应使用迭代器方式3文件写入方法及操作模式说明4文件指针操作和常用辅助参数设置。最佳实践建议始终使用with语句明确指定编码根据场景选择合适方法如大文件用迭代器。常见错误包括编码问题、文件指针位置错误等可通过指定正确编码、seek(0)重置指针等方式解决。使用Python进行文件读写的API或方法及其注意事项以下是 Python 文件读写的核心 API 及注意事项总结表一、文件打开与关闭API/方法功能说明示例注意事项open(file, mode, encoding)打开文件返回文件对象f open(test.txt, r, encodingutf-8)1. 必须指定正确的编码如utf-82. 文件不存在时r模式会报错FileNotFoundError3. 建议使用with语句自动管理资源close()关闭文件对象f.close()1. 忘记关闭可能导致内存泄漏或数据丢失2. 已关闭的文件无法再进行读写操作3. 使用with语句可自动调用with语句上下文管理器自动关闭文件with open(test.txt, r) as f:推荐使用即使发生异常也会自动关闭文件二、文件读取方法API/方法功能说明返回值注意事项read(size-1)读取指定字节数默认读取全部字符串1. 大文件不建议无参读取会耗尽内存2. 读取后文件指针移动到末尾3. 再次调用返回空字符串readline(size-1)读取一行字符串包含换行符\n1. 文件末尾返回空字符串2. 换行符会被保留3. 可用strip()去除换行符readlines(hint-1)读取所有行字符串列表每行含\n1. 大文件同样有内存风险2. 可用for line in f:逐行迭代更高效迭代器方式逐行读取内存友好每行字符串for line in f:process(line)推荐大文件使用不会一次性加载全部内容三、文件写入方法API/方法功能说明示例注意事项write(str)写入字符串f.write(Hello\n)1. 不会自动添加换行符需手动加\n2. 返回写入的字符数3. 需要配合flush()或close()确保写入磁盘writelines(lines)写入字符串列表f.writelines([a\n, b\n])1. 不会自动添加换行符2. 需要自己保证每个元素末尾有\n3. 适用于批量写入flush()强制刷新缓冲区f.flush()立即将缓冲区数据写入磁盘避免数据丢失四、文件操作模式模式说明文件指针位置文件不存在原有内容r只读默认文件开头报错FileNotFoundError保留w只写覆盖文件开头创建新文件清空a追加文件末尾创建新文件保留x独占创建文件开头创建新文件不存在文件存在则报错r读写文件开头报错保留从头覆盖w读写覆盖文件开头创建新文件清空a读追加文件末尾创建新文件保留b二进制模式视主模式而定视主模式而定与文本模式配合使用如rb,wb五、文件指针操作API/方法功能说明示例注意事项tell()返回当前指针位置字节数pos f.tell()1. 文本模式下可能不准确多字节字符2. 二进制模式更可靠seek(offset, whence)移动文件指针f.seek(0, 0)移到开头1.whence: 0开头,1当前位置,2末尾2. 文本模式只支持whence03.offset需配合tell()返回值六、常用辅助操作API/方法功能说明示例注意事项encoding参数指定文件编码encodingutf-81. 必须指定避免平台依赖2. 常用编码utf-8,gbk,gb2312errors参数处理编码错误errorsignore或replace1.ignore忽略错误2.replace用?替换3.strict抛出异常默认newline参数控制换行符处理newline1. 读写 CSV 时建议设为2. 避免跨平台换行符问题七、最佳实践总结场景推荐方法示例代码读小文件100MBread()data f.read()读大文件迭代器for line in f: process(line)读配置文件readlines()或迭代lines f.readlines()写少量数据write()f.write(data)写大量数据writelines()f.writelines(lines)需要随机访问seek()tell()配合二进制模式使用二进制文件图片等rb/wbf.read(1024)分块读取自动资源管理with语句始终推荐八、常见错误与解决方案错误类型典型错误信息解决方案编码错误gbk codec cant decode...指定正确的encoding参数文件不存在FileNotFoundError检查路径或使用w/a模式权限错误PermissionError关闭其他程序占用检查文件只读属性指针错误读到空数据检查是否在read()后忘了seek(0)换行符问题写入内容挤在一行手动添加\n或使用print(filef)九、典型完整示例python# 推荐的标准写法 with open(file.txt, r, encodingutf-8) as f: for line in f: # 逐行读取内存友好 print(line.strip()) # 写入示例 with open(output.txt, w, encodingutf-8) as f: f.write(第一行\n) f.writelines([第二行\n, 第三行\n]) # 无需手动 close()这个表格涵盖了 Python 文件操作的主要 API 和使用要点建议在实际开发中优先使用with语句并明确指定编码。补充文件操作模式以下是 Python 文件操作模式的完整补充包括所有组合模式及详细说明一、基础模式完整版模式读写权限文件指针位置文件不存在原有内容处理典型应用场景r只读开头报错保留读取配置文件、日志分析w只写开头创建清空生成新文件、覆盖旧数据a只写末尾创建保留日志记录、追加数据x只写开头创建独占不存在防止覆盖、创建锁文件r读写开头报错保留修改文件特定位置w读写开头创建清空需要读写的全新文件a读写末尾创建保留追加并读取如日志分析二、二进制模式组合模式说明数据类型换行符处理典型应用rb二进制只读bytes无转换图片、视频、PDF、压缩包wb二进制只写bytes无转换保存图片、序列化数据ab二进制追加bytes无转换合并二进制文件xb二进制独占创建bytes无转换避免覆盖二进制文件rb二进制读写bytes无转换修改二进制文件特定字节wb二进制读写覆盖bytes无转换创建可读写的二进制文件ab二进制读写追加bytes无转换追加并读取二进制数据三、特殊模式组合模式说明行为特点注意事项示例场景rt文本只读默认同r文本模式的标准写法明确指定文本模式wt文本只写同w明确指定文本模式生成文本文件at文本追加同a明确指定文本模式日志追加U通用换行模式已弃用Python 3 中不再使用历史代码兼容四、模式详细行为对比4.1 文件指针位置详解python# 演示不同模式的指针位置 with open(test.txt, w) as f: f.write(1234567890) # r 模式指针在开头 with open(test.txt, r) as f: print(f.tell()) # 0 f.write(ABC) f.seek(0) print(f.read()) # ABC4567890 # a 模式指针在末尾 with open(test.txt, a) as f: print(f.tell()) # 10文件末尾 f.write(XYZ) f.seek(0) print(f.read()) # ABC4567890XYZ4.2 读写操作行为差异模式执行read()执行write()执行seek()缓冲区行为r✅ 可以❌ 报错✅ 可以行缓冲w❌ 报错✅ 可以✅ 可以行缓冲a❌ 报错✅ 可以始终末尾可移动但写操作回到末尾行缓冲r✅ 可以✅ 可以覆盖✅ 可以行缓冲w✅ 可以✅ 可以清空后✅ 可以行缓冲a✅ 可以需先 seek✅ 可以始终末尾读可移动写强制末尾行缓冲4.3 错误处理行为python# 不同模式对错误的处理 import os # 模式 x - 文件存在时报错 try: with open(existing.txt, x) as f: f.write(data) except FileExistsError: print(文件已存在无法创建) # 模式 r - 文件不存在时报错 try: with open(not_exist.txt, r) as f: data f.read() except FileNotFoundError: print(文件不存在) # 模式 w - 自动创建不报错 with open(new_file.txt, w) as f: f.write(自动创建成功)五、平台差异性说明模式Linux/macOS 行为Windows 行为注意事项文本模式换行符\n\r\n自动转换跨平台时注意编码二进制模式无转换无转换推荐处理非文本文件a模式写操作始终末尾写操作始终末尾Windows 某些情况有差异文件锁定通常不锁定可能部分锁定Windows 更严格六、实际应用场景示例6.1 配置文件读写python# 使用 r 读取配置 def read_config(): with open(config.txt, r, encodingutf-8) as f: return dict(line.strip().split() for line in f) # 使用 w 保存配置 def save_config(config): with open(config.txt, w, encodingutf-8) as f: for key, value in config.items(): f.write(f{key}{value}\n)6.2 日志文件追加pythonimport datetime def log_message(msg): # a 模式自动追加不会覆盖历史日志 with open(app.log, a, encodingutf-8) as f: timestamp datetime.datetime.now() f.write(f[{timestamp}] {msg}\n)6.3 二进制文件处理python# 复制图片二进制模式 def copy_image(src, dst): with open(src, rb) as source: with open(dst, wb) as target: # 分块复制避免内存爆炸 while chunk : source.read(8192): target.write(chunk) # 修改二进制文件特定位置 def patch_binary(filepath, offset, new_bytes): with open(filepath, rb) as f: f.seek(offset) f.write(new_bytes)6.4 临时文件安全创建python# 使用 x 模式避免覆盖 def safe_save(data, filename): try: with open(filename, x, encodingutf-8) as f: f.write(data) print(f成功创建 {filename}) except FileExistsError: print(f文件 {filename} 已存在拒绝覆盖) # 可以生成新文件名 base, ext os.path.splitext(filename) new_name f{base}_new{ext} return safe_save(data, new_name)6.5 文件内容原地修改python# 使用 r 模式修改文件特定行 def replace_line(filename, line_num, new_content): with open(filename, r, encodingutf-8) as f: lines f.readlines() if 0 line_num len(lines): lines[line_num] new_content \n f.seek(0) f.writelines(lines) f.truncate() # 截断多余内容6.6 CSV 文件处理pythonimport csv # 读取 CSV文本模式 def read_csv(filename): with open(filename, r, newline, encodingutf-8) as f: return list(csv.reader(f)) # 写入 CSV文本模式 def write_csv(filename, data): with open(filename, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerows(data)七、高级模式与标志位底层 os.openos 标志说明Python 等效用途os.O_RDONLY只读r底层文件操作os.O_WRONLY只写w底层文件操作os.O_RDWR读写r底层文件操作os.O_CREAT不存在则创建w,a自动创建os.O_EXCL与O_CREAT配合独占创建x原子性创建os.O_TRUNC截断文件w清空内容os.O_APPEND追加模式a原子性追加os.O_SYNC同步写入无直接等效性能与可靠性平衡八、性能对比与选择建议场景推荐模式性能特点理由大文件只读r高利用系统缓存频繁小写入a中避免重复 seek随机读写rb低需要多次 seek日志追加a高原子性操作临时文件x高避免冲突二进制拷贝rb,wb高无编码转换开销九、常见陷阱与解决方案陷阱表现解决方案忘记二进制模式图片读写乱码使用rb/wba读不到数据read()返回空先seek(0)再读r意外覆盖写入位置不对精确使用seek()w清空数据原有数据丢失改用a或备份换行符混乱Windows 下\r\n问题二进制模式或指定newline十、完整决策树python# 选择文件模式的决策逻辑 def choose_mode(read_needed, write_needed, append_mode, binary_mode, safe_create): if binary_mode: mode_base b else: mode_base t # 可省略 if read_needed and write_needed: if safe_create: return w mode_base # 安全创建但会清空 elif append_mode: return a mode_base else: return r mode_base elif read_needed: return r mode_base elif write_needed: if safe_create: return x mode_base elif append_mode: return a mode_base else: return w mode_base else: raise ValueError(至少需要读或写权限) # 使用示例 print(choose_mode(True, False, False, False, False)) # r print(choose_mode(True, True, True, False, False)) # a print(choose_mode(False, True, False, True, False)) # wb print(choose_mode(False, True, False, False, True)) # x这个补充涵盖了 Python 文件操作模式的所有细节建议根据具体场景选择合适的模式组合。错误示例错误分析#读文件 with open(C:\\Users\\86178\\Desktop\\aaa.txt,r,encodingutf-8) as f: conf.read()#将文本的内容作为一个整体字符串读出来 con1f.readline() con2 f.readlines()#把文本每行的内容 作为一个元素 放到列表里面 print(con) #输出 # aaa # bbb # ccc print(con1)#换行 print(con2)#[] f.close()#关闭该线程 关闭文件你的代码存在一个关键问题在调用了f.read()之后文件指针已经移动到了文件末尾因此后续的f.readline()和f.readlines()无法再读取到任何内容。问题分析f.read()读取整个文件指针移到最后f.readline()从当前位置文件末尾读取返回空字符串f.readlines()同样从末尾读取返回空列表[]你看到的print(con1)输出空行是因为打印了空字符串后自动换行f.close()其实可以省略with语句会自动关闭修正后的代码方案一只使用一种读取方式pythonwith open(C:\\Users\\86178\\Desktop\\aaa.txt, r, encodingutf-8) as f: con f.read() # 整体读取 print(con)方案二分别读取需要重新打开或重置指针pythonwith open(C:\\Users\\86178\\Desktop\\aaa.txt, r, encodingutf-8) as f: con f.read() print(read()结果) print(con) # 将指针移回文件开头 f.seek(0) con1 f.readline() print(readline()结果, repr(con1)) # 使用repr可以看到转义字符 con2 f.readlines() print(readlines()结果, con2)方案三分别打开文件python# 分别演示三种读取方式 with open(C:\\Users\\86178\\Desktop\\aaa.txt, r, encodingutf-8) as f: print(1. read():) print(f.read()) with open(C:\\Users\\86178\\Desktop\\aaa.txt, r, encodingutf-8) as f: print(\n2. readline():) print(repr(f.readline())) with open(C:\\Users\\86178\\Desktop\\aaa.txt, r, encodingutf-8) as f: print(\n3. readlines():) print(f.readlines())补充说明readline()返回一行字符串包含换行符\n文件末尾返回空字符串readlines()返回所有行的列表每行字符串包含换行符repr()函数可以显示字符串的真实内容包括\n等转义字符seek(0)将文件指针移动到指定位置0表示文件开头类似错误with open(day_07.py,w,encodingutf-8) as f: f.writelines(hello world\n)#覆盖写入 con f.read() print(con)#为什么读不出数据 f.close()问题在于文件指针位置你的代码流程如下问题分析pythonwith open(day_07.py, w, encodingutf-8) as f: f.writelines(hello world\n) # 1. 写入数据指针在末尾第13个字节后 con f.read() # 2. 从末尾读取 → 读不到任何数据 print(con) # 3. 输出空字符串 f.close() # 4. with 语句会自动关闭此行多余关键点writelines()写入后文件指针停留在写入内容的末尾此时调用read()从末尾开始读 → 返回空字符串解决方案方案一先 seek(0) 再读取pythonwith open(day_07.py, w, encodingutf-8) as f: f.writelines(hello world\n) f.seek(0) # 将指针移回文件开头 con f.read() print(con) # 输出: hello world方案二先写入关闭后重新读取python# 先写入 with open(day_07.py, w, encodingutf-8) as f: f.writelines(hello world\n) # 再读取 with open(day_07.py, r, encodingutf-8) as f: con f.read() print(con) # 输出: hello world方案三使用 r 模式需要文件已存在python# 先创建文件 with open(day_07.py, w, encodingutf-8) as f: f.writelines(hello world\n) # 再读写 with open(day_07.py, r, encodingutf-8) as f: con f.read() print(con) # 输出: hello world f.write(\n追加内容) # 在末尾追加各模式写入后的指针位置模式写入操作写入后指针位置立即读取结果wwrite()/writelines()文件末尾空字符串需seek(0)rwrite()写入位置末尾可能覆盖取决于写入位置awrite()始终在文件末尾空字符串需seek(0)wwrite()文件末尾不支持读取验证指针位置python# 演示指针位置变化 with open(day_07.py, w, encodingutf-8) as f: print(f初始位置: {f.tell()}) # 0 f.writelines(hello world\n) print(f写入后位置: {f.tell()}) # 13假设12个字符换行符 f.seek(0) print(fseek(0)后位置: {f.tell()}) # 0 con f.read() print(f读取后位置: {f.tell()}) # 13读完又到末尾 print(f读取内容: {con}) # hello world正确的 w 使用场景w模式适合以下场景场景1写入后立即读取需 seekpythonwith open(temp.txt, w, encodingutf-8) as f: # 生成数据 for i in range(10): f.write(f第{i}行\n) # 需要读取时先回到开头 f.seek(0) data f.read() print(data)场景2清空文件后重新写入并验证pythonwith open(config.txt, w, encodingutf-8) as f: f.write(new config data) f.seek(0) # 验证写入是否正确 if f.read() new config data: print(写入成功)场景3在内存中处理数据python# 使用 StringIO 更好但 w 也可以 with open(data.txt, w, encodingutf-8) as f: # 先生成内容 lines [line1\n, line2\n, line3\n] f.writelines(lines) # 处理这些数据 f.seek(0) processed [line.upper() for line in f] print(processed) # [LINE1\n, LINE2\n, LINE3\n]其他注意事项1. close() 是多余的python# with 语句会自动关闭文件不需要手动 close() with open(day_07.py, w, encodingutf-8) as f: f.write(data) f.seek(0) print(f.read()) # 离开 with 块时自动关闭2.writelines() 不会自动换行python# writelines() 不会自动添加换行符 with open(test.txt, w) as f: f.writelines([hello, world]) # 结果是 helloworld # 需要手动添加 with open(test.txt, w) as f: f.writelines([hello\n, world\n]) # 正确3. 更清晰的替代方案python# 如果只是创建新文件并写入用 w 模式 with open(day_07.py, w, encodingutf-8) as f: f.writelines(hello world\n) # 单独读取 with open(day_07.py, r, encodingutf-8) as f: print(f.read())总结你的代码读不出数据的原因writelines()后指针在文件末尾read()从末尾开始读导致返回空字符串。解决方法在读取前添加f.seek(0)将指针移回开头。最佳实践除非确实需要读写切换否则建议使用单一目的的模式r只读或w只写代码意图更清晰。

更多文章