【问题标题】:buffering argument of open() seemingly ignored when working with text I/O在处理文本 I/O 时,open() 的缓冲参数似乎被忽略了
【发布时间】:2019-01-16 22:59:16
【问题描述】:

在处理文本 I/O 时,内置 open() 函数的缓冲参数似乎被忽略了:

文本输入/输出

>>> f = open("myfile_text.txt", "w",buffering=2)
>>> f.write('1')
1
>>> f.write('1')
1
>>> f.write('1')
1

mymachine:~ myuser$ cat myfile.txt ; echo
mymachine:~ myuser$

二进制 I/O

>>> f = open("myfile_binary.txt", "wb",buffering=2)
>>> f.write('1'.encode())
1
>>> f.write('1'.encode())
1
>>> f.write('1'.encode())
1

mymachine:~ myuser$ cat myfile.txt ; echo
11
mymachine:~ myuser$

为什么?这是预期的行为吗?

【问题讨论】:

  • @AlexanderStrakhov 该链接指向 python 2.7,但这个问题被标记为 python 3。
  • @JohnGordon 这应该是什么意思?来自文档:“缓冲是用于设置缓冲策略的可选整数。传递 0 以关闭缓冲(仅在二进制模式下允许),1 以选择行缓冲(仅在文本模式下可用),整数 > 1 到指示固定大小的块缓冲区的大小(以字节为单位)。"
  • @SimónRamírezAmaya 前面评论中链接的答案引用了 2.7 文档,它说它是一个近似大小。 3.6的文档不同,没有说大概的。
  • 我很抱歉;我误读了文档。我将删除我之前的评论。

标签: python python-3.x io buffer


【解决方案1】:

我已经浏览了一下。事实上,文档指出:

buffering 是一个可选的整数,用于设置缓冲策略。传递 0 关闭缓冲(仅在二进制模式下允许),1 选择行缓冲(仅在文本模式下可用),整数 > 1 表示固定大小的块缓冲区的大小(以字节为单位)...

因此可以合理地预期指定buffering=2 将导致使用大小为2B 的缓冲区(并在使用该缓冲区时查看文件刷新)。然而,在文本模式下,它似乎(并且文档并没有真正清楚地表明在这个地方)会影响下划线BufferedWriter,但是你最终调用的TextIOWrapperwrite() 仍然是“它自己的事情”。 .. 从 Python 3.7 开始,您告诉它不要这样做,并通过在您打开的文件上调用 f.reconfigure(write_through=True) 让它立即将写入传递给底层对象。


实际上,write_through 的所有代码和值检查都已经在 Python 3.6 中(我检查了 3.6.8)(事实上,_io_TextIOWrapper_write_impl,即_io.TextIOWrapper.write,在两个版本中都是相同的) ,但write_through 属性尚未公开。

【讨论】:

  • 感谢您的研究。那么我们必须明确声明 TextIOWrapper 将写入传递给 BufferedWriter 是否意味着原始 open(..., buffering = 2) 参数不会影响 TextIOWrapper 缓冲区的大小?
  • _io.TextIOWrapper 本身的确实缓冲区目前在内部被硬编码为 8kB。
猜你喜欢
  • 2021-10-28
  • 2016-09-30
  • 2012-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 2012-03-08
相关资源
最近更新 更多