【问题标题】:writing back into the same file after reading from the file从文件读取后写回同一个文件
【发布时间】:2013-07-12 20:54:36
【问题描述】:

我的目标是从文件中读取行,去掉它末尾的空格并写回到同一个文件中。我试过以下代码:

with open(filename, 'r+') as f:
    for i in f:
        f.write(i.rstrip()+"\n")

这似乎写在文件的末尾,保持文件中的初始数据完好无损。我知道使用 f.seek(0) 会将指针带回到文件的开头,我假设此解决方案需要它。

您能否告知是否有不同的方法,或者我是否在正确的补丁中只需要在代码中添加更多逻辑?

【问题讨论】:

    标签: python file io python-2.6


    【解决方案1】:

    使用临时文件。 Python 提供了以安全方式创建临时文件的工具。调用下面的示例:python modify.py target_filename

     import tempfile
     import sys
    
     def modify_file(filename):
    
          #Create temporary file read/write
          t = tempfile.NamedTemporaryFile(mode="r+")
    
          #Open input file read-only
          i = open(filename, 'r')
    
          #Copy input file to temporary file, modifying as we go
          for line in i:
               t.write(line.rstrip()+"\n")
    
          i.close() #Close input file
    
          t.seek(0) #Rewind temporary file to beginning
    
          o = open(filename, "w")  #Reopen input file writable
    
          #Overwriting original file with temporary file contents          
          for line in t:
               o.write(line)  
    
          t.close() #Close temporary file, will cause it to be deleted
    
     if __name__ == "__main__":
          modify_file(sys.argv[1])
    

    参考资料: http://docs.python.org/2/library/tempfile.html

    【讨论】:

    • 很好的例子和很好的解释。
    • 谢谢。即使内存可用,我也喜欢使用临时文件。另请查看 tempfile 文档中的假脱机临时文件,这是一个有趣的折衷方案。
    【解决方案2】:

    您的方法的问题是您需要输入流和输出流,它们可以指向同一文件中的不同位置。如果要使用f.seek(),则需要在每次读写后使用f.tell() 存储位置。例如:

    f = open(filename, 'r+')
    while True:
        i = f.readline()
        if i == '': break
        in = f.tell()
        f.seek(out)
        f.write(i.rstrip()+"\n")
        out = f.tell()
        f.seek(in)
    

    但这很令人困惑并且容易出错。如果文件不是太大,为什么不把它全部读入内存,然后再写回去呢?

    in = open(filename, 'r')
    lines = in.read()
    in.close()
    out = open(filename, 'w')
    out.write([line.rstrip()+'\n' for line in lines.split('\n')])
    out.close()
    

    如果文件太大而无法放入内存,则将这些行写入临时文件,然后在完成后重命名文件:

    out = open(filename+'.tmp', 'w')
    with open(filename, 'r') as f:
        for i in f:
            out.write(i.rstrip()+"\n")
    out.close()
    os.rename(filename+'.tmp', filename)
    

    【讨论】:

    • 您的最后一个解决方案似乎几乎解决了问题,唯一剩下的问题是,我希望更改新文件名,即新文件应该替换旧文件。如果我按照上面指定的方法来做,我会得到WindowsError: [Error 183] Cannot create a file when that file already exists
    • 这很简单,只需在关闭旧文件后重命名之前删除它:os.remove(filename)
    • 嗨,我决定使用方法 2,将文件的内容存储到内存中,但是当我执行代码时出现错误 TypeError: write() argument must be str, not list,您能帮忙吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-23
    • 2021-04-29
    • 2012-10-22
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多