Python 3.6.3中open()指定缓冲区大小不生效问题求助
Python 3中文件缓冲区大小未按指定值生效的问题分析与解决
这是个挺有意思的版本差异问题!我来帮你拆解一下原因,再给你可行的解决办法。
问题根源:Python 2 vs Python 3的buffering参数逻辑差异
你遇到的核心问题是Python 3对文本模式下的buffering参数处理逻辑和Python 2不一样:
- 在Python 2中,不管是文本模式还是二进制模式,只要给
buffering传入大于0的整数,就会严格使用你指定的缓冲区大小。 - 但在Python 3中:
- 当文件以二进制模式(比如
'wb')打开时,buffering的整数参数才会精确生效; - 当文件以文本模式(默认的
'w'就是文本模式)打开时,你传入的buffering值只是一个“建议值”,Python会自动对齐到系统的默认块大小(通常是8KB/8192字节),而且会优先考虑行缓冲的逻辑。
- 当文件以二进制模式(比如
你的代码里用的是open(_File, 'w', 5000),属于文本模式,所以Python 3直接忽略了5000这个值,用了系统默认的8KB缓冲区,这就是和Python 2表现不同的原因。
解决办法
办法1:改用二进制模式写入(适合简单文本场景)
如果你的日志内容都是简单的ASCII文本,可以直接切换到二进制模式,这样缓冲区大小就会严格按照你指定的5KB来:
import sys, time, os _File = 'TemperatureData1.csv' _newDir = '/home/pi/Documents/Temperature Data Logs' os.chdir(_newDir) # 改用二进制模式'wb',指定5000字节缓冲区 output = open(_File, 'wb', 5000) try: while (1): # 写入字节串,而非字符串 output.write(b'hi\n') time.sleep(0.01) except KeyboardInterrupt: print('Keyboard has been pressed') output.close() sys.exit(1)
如果需要写入非ASCII字符,记得先把字符串编码成字节串,比如output.write('温度数据\n'.encode('utf-8'))。
办法2:用io.TextIOWrapper包装二进制文件(保留文本模式的便利)
如果你想继续使用文本模式的便捷性(直接写字符串、自动处理编码),可以先以二进制模式打开文件,再用io.TextIOWrapper包装,这样既能指定精确的缓冲区大小,又能正常写文本:
import sys, time, os, io _File = 'TemperatureData1.csv' _newDir = '/home/pi/Documents/Temperature Data Logs' os.chdir(_newDir) # 先以二进制模式打开,指定5000字节缓冲区 binary_file = open(_File, 'wb', 5000) # 包装成文本模式的文件对象,指定编码 output = io.TextIOWrapper(binary_file, encoding='utf-8') try: while (1): # 直接写字符串即可 output.write('hi\n') time.sleep(0.01) except KeyboardInterrupt: print('Keyboard has been pressed') output.close() binary_file.close() sys.exit(1)
补充说明
Python 3的这个改动是因为文本模式涉及到换行符转换(比如Windows的\r\n和Unix的\n)、字符编码解码等额外逻辑,和二进制模式的缓冲区管理完全不同,所以官方调整了参数的生效规则。这个差异在Python社区里是被广泛知晓的,不少开发者在从Python 2迁移到3的时候都遇到过类似问题。
内容的提问来源于stack exchange,提问作者Thomas Sutton
相关产品推荐
相关产品推荐

