我目前正在使用Raspberry Pi创建数据记录功能,我不确定是否发现了一个小错误。我使用的代码如下:
import sys, time, os
_File = 'TemperatureData1.csv'
_newDir = '/home/pi/Documents/Temperature Data Logs'
_directoryList = os.listdir(_newDir)
os.chdir(_newDir)
# Here I am specifying the file, that I want to write to it, and that
# I want to use a buffer of 5kb
output = open(_File, 'w', 5000)
try:
while (1):
output.write('hi\n')
time.sleep(0.01)
except KeyboardInterrupt:
print('Keyboard has been pressed')
output.close()
sys.exit(1)
我发现当我定期查看创建的文件属性时,文件大小会根据默认缓冲区设置8192字节增加,而不是我指定的5kb。但是,当我在Python 2.7.13中运行完全相同的程序时,缓冲区大小会根据请求变为5kb。
我想知道是否有其他人有过这方面的想法并且对于使程序在Python 3.6.3上运行的解决方案有什么想法?提前致谢。我可以在python 2.7.13上解决这个问题,这是我纯粹的好奇心导致我发布这个问题。
答案 0 :(得分:1)
Python在版本2中对open
的定义就是您所使用的:
open(name[, mode[, buffering]])
在Python 3中,open
命令略有不同,因为buffering
不是位置整数,而是关键字arg:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
docs有以下注释:
buffering
是一个可选的整数,用于设置缓冲策略。通过0
关闭缓冲关闭(仅允许二进制模式),1
选择行缓冲(仅在文本模式下可用),以及整数>1
表示固定大小的块缓冲区的大小(以字节为单位)。如果没有给出缓冲参数,则默认缓冲策略的工作方式如下:二进制文件以固定大小的块缓冲;使用启发式方法选择缓冲区的大小,尝试确定底层设备的“块大小”并回退到io.DEFAULT_BUFFER_SIZE。在许多系统上,缓冲区通常为4096或8192字节长。 “交互式”文本文件(isatty()返回True的文件)使用行缓冲。其他文本文件使用上述策略用于二进制文件。
那个特殊的8192
号码只是2 ^ 13。
我建议您尝试buffering=5000
。
答案 1 :(得分:1)
我做了更多的研究,并设法找到了为什么要设置缓冲'如果值大于1,则不会在python 3或更高版本中手动将缓冲区操作为所需的大小(字节)。
这似乎是因为io库在处理文件,文本缓冲区和二进制缓冲区时使用了两个缓冲区。当处于文本模式时,根据文本缓冲区刷新文件(当缓冲> 1时似乎不能操作该文件缓冲区)。相反,缓冲参数操纵二进制缓冲区,然后将其提供给文本缓冲区,因此缓冲函数不适用于程序员期望的方式。这在以下链接中进一步解释:
https://bugs.python.org/issue30718
然而,有一种解决方法;你需要在二进制模式而不是文本模式下使用open(),然后使用io.TextIOWrapper函数使用二进制缓冲区写入txt或csv文件。解决方法如下: import sys, time, os, io
_File = 'TemperatureData1.csv'
# Open or overwrite the file _file, and use a 20kb buffer in RAM
# before data is saved to disk.
output = open(_File, mode='wb', buffering=700)
output = io.TextIOWrapper(output, write_through=True)
try:
while (1):
output.write('h\n')
time.sleep(0.01)
except KeyboardInterrupt:
print('Keyboard has been pressed')
output.close()
sys.exit(1)