【问题标题】:Attempting to read open file a second time gets no data尝试第二次读取打开的文件没有数据
【发布时间】:2012-05-27 09:29:49
【问题描述】:
fin = open('/abc/xyz/test.txt', 'a+')

def lst():
  return fin.read().splitlines()

print lst()

def foo(in):
  print lst()
  fin.write(str(len(lst()) + in)
  fin.flush()

在上面的代码中,当print lst() 在函数外被调用时,它会给出正确的结果,但是当尝试在函数foo() 中调用相同的函数时,它会产生空列表,这使得len(lst()) 的值为0。我也尝试通过评论最后两个行,但它仍然返回空列表。上面的代码有什么问题?

【问题讨论】:

  • 你为什么在opening fin外面lst()
  • 当你尝试 foo() 中的第一个 lst() 调用时,你会注释掉吗?
  • @olovb 不。我只是为了检查 lst() 是否返回预期值。
  • 请注意,您应该尝试使用the with statement 在 Python 中打开文件。它更具可读性并确保您的文件已关闭,即使抛出异常也是如此。
  • @Lattyware 请用代码说明。

标签: python


【解决方案1】:

文件对象被读取一次。一旦fin 变为read(),您将无法再从文件中读取任何其他内容,因为它已经到达EOF

要读取文件的内容,调用 f.read(size),它会读取一些 数据量并将其作为字符串返回。尺寸是可选的 数字参数。当 size 被省略或为负时,整个 文件内容将被读取并返回;这是你的问题,如果 该文件是机器内存的两倍。否则,在 大多数 size 字节被读取并返回。如果文件的结尾已经 达到,f.read() 将返回一个空字符串 ("")。

http://docs.python.org/tutorial/inputoutput.html#methods-of-file-objects

如果您确实需要对文件进行可重入访问,请使用:

def lst():
  fin.seek(0)
  return fin.readlines()

【讨论】:

    【解决方案2】:

    一旦你将一个完整的文件读入内存,从该文件中读取更多内容将导致返回一个空字符串:

    >>> example = open('foobar.txt')
    >>> example.read()
    'Foo Bar\n'
    >>> example.read()
    ''
    

    换句话说,您已到达文件末尾。您在这里有三种选择:

    1. 每次完整读取时重新打开文件。
    2. 使用.seek() 再次转到文件的开头:

      >>> example = open('foobar.txt')
      >>> example.read()
      'Foo Bar\n'
      >>> example.seek(0)
      >>> example.read()
      'Foo Bar\n'
      
    3. 将文件的内容存储在一个变量中,从而将其缓存在内存中,然后使用它而不是重新读取文件。

    【讨论】:

      【解决方案3】:

      一旦您调用了read(),一旦fin 被读取。

      如果你想再次read()它(在第一次尝试时丢弃了内容),你需要重新open()seek()文件的开头。

      我建议您在lst() 中执行此操作,或者更好的是,将lst() 返回的内容存储起来

      除此之外……

      fin.write(str(len(lst()) + in)
      

      目前尚不清楚您要在这里做什么,但最好使用来自lst() 的存储返回值,而不是使用in 作为变量名,因为它是保留的keyword

      类似:

      lines = lst()
      # [...]
      number_of_lines = len(lines)
      fin.write(str(number_of_lines) + some_other_str)
      

      【讨论】:

      • 我认为fin.flush 将存储在 I/O 缓冲区中的更改写入文件。我使用它是因为我没有使用file.close()函数。
      • 如果我使用fin.flush() 更新'fin',bar = fin.read() 会发生什么?还会更新吗?
      • @Alinwndrld:不,不会。试试看!
      【解决方案4】:

      文件对象只能读取一次,这意味着如果您在后面的 fin.read() 之前调用了fin.read(),则不会返回任何内容。

      在调用 fin.read() 后通过调用 fin.seek(0) 修复此问题,或将文件读取到某个缓冲区。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-08
        • 1970-01-01
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        相关资源
        最近更新 更多