Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么file_object.tell()为不同位置的文件提供相同的字节?_Python_Python 2.7 - Fatal编程技术网

Python 为什么file_object.tell()为不同位置的文件提供相同的字节?

Python 为什么file_object.tell()为不同位置的文件提供相同的字节?,python,python-2.7,Python,Python 2.7,我刚刚开始学习python,无法绕过基本的文件导航方法 当我阅读教程时,它声明它返回我当前在文件中的位置(以字节为单位) 我的推理是,文件中的每个字符加起来就是字节坐标,对吗?这意味着在一个新行之后,这只是在\n字符上拆分的一个字符串,我的字节坐标将改变。。。但这似乎是不正确的 我在bash上生成了一个快速玩具文本文件 $ for i in {1..10}; do echo "@ this is the "$i"th line" ; done > toy.txt $ for i in {1

我刚刚开始学习python,无法绕过基本的文件导航方法

当我阅读教程时,它声明它返回我当前在文件中的位置(以字节为单位)

我的推理是,文件中的每个字符加起来就是字节坐标,对吗?这意味着在一个新行之后,这只是在
\n
字符上拆分的一个字符串,我的字节坐标将改变。。。但这似乎是不正确的

我在bash上生成了一个快速玩具文本文件

$ for i in {1..10}; do echo "@ this is the "$i"th line" ; done > toy.txt
$ for i in {11..20}; do echo " this is the "$i"th line" ; done >> toy.txt
现在我将遍历这个文件并打印出行号和每个周期的
tell()
调用的结果。
@
用于标记一些分隔文件块的行,我想返回这些行(见下文)

我的猜测是for循环首先在file对象上迭代,到达它的末尾,因此它始终保持不变

这是一个很好的例子,在我真正的问题上,文件的长度是Gigs,通过应用相同的方法,我得到的结果是,
tell()
在我的图像块中反映了for循环是如何在file对象上迭代的。 这是正确的吗?你能解释一下我所缺少的概念吗

我的最终目标是能够定位文件中的特定坐标,然后并行处理这些来自分布式起点的巨大文件,我无法以筛选它们的方式监视这些文件

os.path.getsize("toy.txt")
451

fa = open("toy.txt")
fa.seek(0) # let's double check
fa.tell()
count = 0
for line in fa:
    if line.startswith("@"):
        print line ,
        print "tell {} count {}".format(fa.tell(), count)
    else:
        if count < 32775:
            print line,
            print "tell {} count {}".format(fa.tell(), count)
    count += 1

迭代文件时,文件不一定位于循环锯的最后一个字符处。

迭代文件时,文件不一定位于循环锯的最后一个字符处。

您正在使用
for
循环逐行读取文件:

for line in fa:
文件通常不会这样做;您可以读取数据块,通常是数据块。为了让Python给您换行,您需要一直读到下一行。只是,逐字节读取以查找换行符不是很有效

因此使用了缓冲区;你读一个大段,然后在该段中找到换行符,并为找到的每一个换行符生成一行。缓冲区用完后,您将读取一个新块

您的文件大小不足以读取多个块;它只有451字节小,而缓冲区通常以千字节为单位。如果您要创建一个更大的文件,您将在迭代时看到文件位置以大步跳转

参见(
next
是迭代时负责生成下一行的方法,
for
循环所做的工作):

为了使for循环成为在文件行上循环的最有效方式(一种非常常见的操作),
next()
方法使用隐藏的预读缓冲区

如果在行上循环时需要跟踪绝对文件位置,则必须在Windows上使用二进制模式If(以防止换行转换发生),并自己跟踪行长度:

position = 0    
for line in fa:
    position += len(line)
另一种选择是使用;这是Python3中用于处理文件的框架。
file.tell()
方法将缓冲区考虑在内,即使在迭代时也会生成准确的文件位置

考虑到当您使用文本模式打开文件时,您将获得
unicode
字符串。在Python2中,如果必须使用
str
bytestrings,则可以使用二进制模式(用
'rb'
打开)。事实上,只有在二进制模式下,您才能访问
IOBase.tell()
,而在文本模式下会引发异常:

>>> import io
>>> fa = io.open("toy.txt")
>>> next(fa)
u'@ this is the 1th line\n'
>>> fa.tell()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: telling position disabled by next() call

您正在使用
for
循环逐行读取文件:

for line in fa:
文件通常不会这样做;您可以读取数据块,通常是数据块。为了让Python给您换行,您需要一直读到下一行。只是,逐字节读取以查找换行符不是很有效

因此使用了缓冲区;你读一个大段,然后在该段中找到换行符,并为找到的每一个换行符生成一行。缓冲区用完后,您将读取一个新块

您的文件大小不足以读取多个块;它只有451字节小,而缓冲区通常以千字节为单位。如果您要创建一个更大的文件,您将在迭代时看到文件位置以大步跳转

参见(
next
是迭代时负责生成下一行的方法,
for
循环所做的工作):

为了使for循环成为在文件行上循环的最有效方式(一种非常常见的操作),
next()
方法使用隐藏的预读缓冲区

如果在行上循环时需要跟踪绝对文件位置,则必须在Windows上使用二进制模式If(以防止换行转换发生),并自己跟踪行长度:

position = 0    
for line in fa:
    position += len(line)
另一种选择是使用;这是Python3中用于处理文件的框架。
file.tell()
方法将缓冲区考虑在内,即使在迭代时也会生成准确的文件位置

考虑到当您使用文本模式打开文件时,您将获得
unicode
字符串。在Python2中,如果必须使用
str
bytestrings,则可以使用二进制模式(用
'rb'
打开)。事实上,只有在二进制模式下,您才能访问
IOBase.tell()
,而在文本模式下会引发异常:

>>> import io
>>> fa = io.open("toy.txt")
>>> next(fa)
u'@ this is the 1th line\n'
>>> fa.tell()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: telling position disabled by next() call