我正在使用Python,并希望在不删除或复制文件的情况下将字符串插入文本文件中.我怎样才能做到这一点?
不幸的是,如果不重写它,就无法插入文件的中间.如前面的海报所示,您可以使用搜索附加到文件或覆盖部分文件,但如果您想在开头或中间添加内容,则必须重写它.
这是一个操作系统的东西,而不是Python的东西.所有语言都是一样的.
我通常做的是从文件中读取,进行修改并将其写入名为myfile.txt.tmp的新文件或类似的东西.这比将整个文件读入内存要好,因为文件可能太大了.临时文件完成后,我将其重命名为原始文件.
这是一种很好的,安全的方法,因为如果文件写入由于任何原因而崩溃或中止,您仍然拥有未触及的原始文件.
取决于你想做什么.要追加你可以用"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
fileinput
如果使用inplace = 1参数,Python标准库的模块将在本地重写文件:
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
通常使用修改后的名称保存旧副本来重写文件.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: 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 - 这可能是很大.
正如亚当所提到的,你必须考虑系统限制,然后才能决定是否有足够的内存将其全部读入内存替换它的一部分并重新编写它.
如果您正在处理小文件或没有内存问题,这可能会有所帮助:
选项1)将 整个文件读入内存,在整个或部分行上进行正则表达式替换,并用该行加上额外的行替换它.您需要确保文件中的"中间行"是唯一的,或者如果每行都有时间戳,这应该非常可靠.
# open file with r+b (allow write and binary mode) f = open("file.log", 'r+b') # read entire content of file into memory f_content = f.read() # basically match middle line and replace it with itself and the extra line f_content = re.sub(r'(middle line)', r'\1\nnew line', f_content) # return pointer to top of file so we can re-write the content with replaced string f.seek(0) # clear file content f.truncate() # re-write the content with the updated content f.write(f_content) # close file f.close()
选项2) 找出中间线,并用该线加上额外线替换它.
# open file with r+b (allow write and binary mode) f = open("file.log" , 'r+b') # get array of lines f_content = f.readlines() # get middle line middle_line = len(f_content)/2 # overwrite middle line f_content[middle_line] += "\nnew line" # return pointer to top of file so we can re-write the content with replaced string f.seek(0) # clear file content f.truncate() # re-write the content with the updated content f.write(''.join(f_content)) # close file f.close()