如何在文件上使用write()方法而不替换字符?

时间:2018-12-24 19:21:30

标签: python text-files file-writing

我有一个.txt文件,其内容为:

This is an example file.
These are its contents.
This is line 3.

如果我打开文件,请移至开头,然后像这样写一些文字...

f = open(r'C:\Users\piano\Documents\sample.txt', 'r+')
f.seek(0, 0)
f.write('Now I am adding text.\n')

我希望文件能够读取:

Now I am adding text.
This is an example file.
These are its contents.
This is line 3.

...但改为:

Now I am adding text.
.
These are its contents.
This is line 3.

那为什么为什么要替换某些文本而不是将我正在编写的文本简单地添加到开头呢?我该如何解决?

2 个答案:

答案 0 :(得分:1)

写入-将覆盖所有现有内容
为了克服这个问题,您可以执行以下操作:

with open(r'C:\Users\piano\Documents\sample.txt', 'r+') as file:
    string = file.read()
    file.truncate(0) #delete all contents
    file.seek(0, 0)
    file.write('Now I am adding text.\n' + string)

还建议您使用with,因为它的close()魔术方法中的__exit__()方法是自动提供的。这很重要,因为并非所有的Python解释器都使用CPython

奖金:如果您希望在两者之间插入行,可以这样做:

with open(r'C:\Users\piano\Documents\sample.txt', 'r+') as file:
    contents = file.readlines()
    contents.insert(1, 'Now I am adding text.\n') 
    #Inserting into second line
    file.truncate(0) #delete all contents
    file.seek(0, 0)
    file.writelines(contents)

答案 1 :(得分:0)

大多数文件系统不能那样工作。文件的内容映射到数据块,并且不能保证这些数据块在基础系统上是连续的(即不一定“并排”)。

寻找时,您要寻找一个字节偏移量。因此,如果要在特定块的2个字节的偏移量之间插入新数据,则实际上必须将所有后续数据移位所插入的长度。由于该块很容易被完全“填充”,因此将字节移位可能需要分配一个新块。如果随后的块也被完全“填充”,则还必须移动该块的数据,依此类推。.您可以开始了解为什么没有“简单”的数据移位操作。

通常,我们通过将所有数据读入内存,然后将其重新写回文件来解决此问题。当您遇到有兴趣插入“新”内容的字节偏移量时,您将写入缓冲区,然后继续写入“原始”数据。在Python中,您无需担心写入时交错多个缓冲区,因为Python会将数据抽象为某种数据结构。因此,您只需串联更高级别的数据结构(例如,如果是文本文件,则只需串联3个字符串)。

如果文件太大而无法舒适地放置在内存中,则可以写入“新”临时文件,然后在完成写操作后将其与原始文件交换。


现在,如果您考虑上面提到的数据块中数据的“移位”,则可以考虑使用最简单的边缘情况,即碰巧以N的倍数的偏移量插入长度为N的数据,其中N是文件系统中数据块的固定大小。在这种情况下,如果您将数据块视为链接列表,则可以认为在插入的偏移量和列表中的下一个块之间添加新的数据块是一种相当简单的操作。

实际上,Linux系统确实支持在此边界处分配额外的块。参见fallocate