如何修改文本文件?

时间:2020-03-06 14:38:45  来源:igfitidea点击:

我正在使用Python,并且想在不删除或者复制文件的情况下将字符串插入文本文件。我怎样才能做到这一点?

解决方案

取决于我们要做什么。要追加,我们可以使用" a"打开它:

with open("foo.txt", "a") as f:
     f.write("new line\n")

如果要先添加某些内容,则必须先从文件中读取:

with open("foo.txt", "r+") as f:
     old = f.read() # read everything in the file
     f.seek(0) # rewind
     f.write("new line\n" + old) # write the new line before

不幸的是,没有重写就无法插入文件中间。如先前的张贴者所指出的,我们可以将文件追加到文件中或者使用"搜索"覆盖文件的一部分,但是如果要在文件的开头或者中间添加内容,则必须重写它。

这是操作系统的东西,而不是Python的东西。所有语言均相同。

我通常要做的是从文件中读取,进行修改并将其写到名为myfile.txt.tmp或者类似名称的新文件中。这比将整个文件读入内存要好,因为文件可能太大了。临时文件完成后,我将其重命名为原始文件。

这是一种很好的安全方法,因为如果文件写入由于任何原因而崩溃或者中止,我们仍然可以拥有原始文件。

通常,通过使用修改后的名称保存旧副本来原地重写文件。 Unix人士添加一个〜来标记旧的。 Windows使用者可以做各种各样的事情-添加.bak或者.old-或者完全重命名该文件,或者在该名称的前面加上〜。

import shutil
shutil.move( afile, afile+"~" )

destination= open( aFile, "w" )
source= open( aFile+"~", "r" )
for line in source:
    destination.write( line )
    if <some condition>:
        destination.write( >some additional line> + "\n" )
source.close()
destination.close()

代替shutil,我们可以使用以下命令。

import os
os.rename( aFile, aFile+"~" )

Python的mmap模块将允许我们插入文件中。以下示例显示了如何在Unix中完成此操作(Windows mmap可能有所不同)。请注意,这不能处理所有错误情况,并且我们可能损坏或者丢失原始文件。另外,这将无法处理unicode字符串。

import os
from mmap import mmap

def insert(filename, str, pos):
    if len(str) < 1:
        # nothing to insert
        return

    f = open(filename, 'r+')
    m = mmap(f.fileno(), os.path.getsize(filename))
    origSize = m.size()

    # or this could be an error
    if pos > origSize:
        pos = origSize
    elif pos < 0:
        pos = 0

    m.resize(origSize + len(str))
    m[pos+len(str):] = m[pos:origSize]
    m[pos:pos+len(str)] = str
    m.close()
    f.close()

也可以不使用mmap在" r +"模式下打开文件而执行此操作,但是这样做不方便且效率较低,因为我们必须读取并临时将文件内容从插入位置存储到EOF,这可能是巨大的。

如果我们使用inplace = 1参数,Python标准库的fileinput模块将就地重写文件:

import sys
import fileinput

# replace all occurrences of 'sit' with 'SIT' and insert a line after the 5th
for i, line in enumerate(fileinput.input('lorem_ipsum.txt', inplace=1)):
    sys.stdout.write(line.replace('sit', 'SIT'))  # replace 'sit' and write
    if i == 4: sys.stdout.write('\n')  # write a blank line after the 5th line