gpt4 book ai didi

python - 为什么截断不能正确默认为文件的当前位置?

转载 作者:太空狗 更新时间:2023-10-30 01:06:50 27 4
gpt4 key购买 nike

在对 another question 的回答中,观察到一个奇怪的行为,特定于 Python 3。 documentation for the truncate command状态(强调我的):

Resize the stream to the given size in bytes (or the current position if size is not specified). The current stream position isn’t changed. This resizing can extend or reduce the current file size. In case of extension, the contents of the new file area depend on the platform (on most systems, additional bytes are zero-filled). The new file size is returned.

然而...

>>> open('temp.txt', 'w').write('ABCDE\nFGHIJ\nKLMNO\nPQRST\nUVWXY\nZ\n')
32
>>> f = open('temp.txt', 'r+')
>>> f.readline()
'ABCDE\n'
>>> f.tell()
6 # As expected, current position is 6 after the readline
>>> f.truncate()
32 # ?!

它不是在当前位置 (6) 截断,而是在文件末尾截断(即根本不截断)。通过检查磁盘上的文件验证了这一点。

此过程在 Python 2 中按预期工作(文件被截断为 6 个字节),在使用 StringIO 而不是文件的 Python 3 中也是如此。为什么在 Python 3 中不能按预期处理文件?这是错误吗?

(编辑:如果在 truncate 之前给出明确的 f.seek(6),它也能正常工作。)

最佳答案

>>> open('temp.txt', 'w').write('ABCDE\nFGHIJ\nKLMNO\nPQRST\nUVWXY\nZ\n')
32
>>> f = open('temp.txt', 'r+')
>>> f.readline()
'ABCDE\n'
>>> f.seek(6)
>>> f.truncate()

如果没有别的,这解决了这个问题,至于为什么会发生我不知道,但如果还没有报告这个上游是一件好事。

这些是我能找到的 Python3 和 Python2 之间的 truncate() 函数的唯一结构差异(显然截断函数本身内的相关函数调用除外):

33,34c33,34
< except AttributeError as err:
< raise TypeError("an integer is required") from err
---
> except AttributeError:
> raise TypeError("an integer is required")
54c54
< """Truncate size to pos, where pos is an int."""
---
> """Truncate size to pos."""

我敢肯定有人会指责我这个主题,但我认为它与 flush() 调用以及调用 flush 后缓冲区的处理方式更相关。几乎就像在刷新所有 I/O 后它没有重置到以前的位置一样。这是一个大胆的假设,还没有任何技术支持,但这将是我的第一个猜测。

查看了flush()的情况,这是两者之间唯一的区别,其中Python2执行了以下操作,而Python3没有(甚至缺少它的源代码):

def _flush_unlocked(self):
if self.closed:
raise ValueError("flush of closed file")
while self._write_buf:
try:
n = self.raw.write(self._write_buf)
except BlockingIOError:
raise RuntimeError("self.raw should implement RawIOBase: it "
"should not raise BlockingIOError")
except IOError as e:
if e.errno != EINTR:
raise
continue
if n is None:
raise BlockingIOError(
errno.EAGAIN,
"write could not complete without blocking", 0)
if n > len(self._write_buf) or n < 0:
raise IOError("write() returned incorrect number of bytes")
del self._write_buf[:n]

它是 BufferedWriter 的一个函数,似乎用在这个 I/O 操作中。
现在我约会要迟到了,所以得赶快,看看你们同时发现了什么会很有趣!

关于python - 为什么截断不能正确默认为文件的当前位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34879318/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com