简体   繁体   English

Python:读取一行并写回同一行

[英]Python: read a line and write back to that same line

I am using python to make a template updater for html. 我正在使用python为html制作模板更新程序。 I read a line and compare it with the template file to see if there are any changes that needs to be updated. 我读了一行并将其与模板文件进行比较,看看是否有任何需要更新的更改。 Then I want to write any changes (if there are any) back to the same line I just read from. 然后我想把任何更改(如果有的话)写回我刚才读的同一行。

Reading the file, my file pointer is positioned now on the next line after a readline(). 读取文件后,我的文件指针现在位于readline()之后的下一行。 Is there anyway I can write back to the same line without having to open two file handles for reading and writing? 无论如何,我可以回写到同一行,而无需打开两个文件句柄进行读写操作?

Here is a code snippet of what I want to do: 这是我想要做的代码片段:

cLine = fp.readline()
if cLine != templateLine:
   # Here is where I would like to write back to the line I read from
   # in cLine

Updating lines in place in text file - very difficult 在文本文件中更新行 - 非常困难

Many questions in SO are trying to read the file and update it at once. SO中的许多问题都是尝试读取文件并立即更新。

While this is technically possible, it is very difficult. 虽然这在技术上是可行的,但是非常困难。

(text) files are not organized on disk by lines, but by bytes. (文本)文件不是按行排列在磁盘上,而是按字节排列。

The problem is, that read number of bytes on old lines is very often different from new one, and this mess up the resulting file. 问题是,读取旧行上的字节数通常与新行不同,这会弄乱生成的文件。

Update by creating a new file 通过创建新文件进行更新

While it sounds inefficient, it is the most effective way from programming point of view. 虽然听起来效率低,但从编程的角度来看,这是最有效的方法。

Just read from file on one side, write to another file on the other side, close the files and copy the content from newly created over the old one. 只需从一侧的文件中读取,写入另一侧的另一个文件,关闭文件并复制新创建的内容。

Or create the file in memory and finally do the writing over the old one after you close the old one. 或者在内存中创建文件,最后在关闭旧文件后再写入旧文件。

At the OS level the things are a bit different from how it looks from Python - from Python a file looks almost like a list of strings, with each string having arbitrary length, so it seems to be easy to swap a line for something else without affecting the rest of the lines: 在操作系统级别,它与Python的外观有点不同 - 从Python开始,文件看起来几乎就像一个字符串列表,每个字符串都有任意长度,所以看起来很容易换行而不用影响其余部分:

l = ["Hello", "world"]
l[0] = "Good bye"

In reality, though, any file is just a stream of bytes, with strings following each other without any "padding". 但实际上,任何文件都只是一个字节流,字符串彼此跟随而没有任何“填充”。 So you can only overwrite the data in-place if the resulting string has exactly the same length as the source string - otherwise it'll simply overwrite the following lines. 因此,如果结果字符串的长度与源字符串的长度完全相同,则只能就地覆盖数据 - 否则它只会覆盖以下行。

If that is the case (your processing guarantees not to change the length of strings), you can "rewind" the file to the start of the line and overwrite the line with new data. 如果是这种情况(您的处理保证不更改字符串的长度),您可以将文件“倒回”到行的开头并用新数据覆盖该行。 The below script converts all lines in file to uppercase in-place: 下面的脚本将文件中的所有行转换为原位大写:

def eof(f):
    cur_loc = f.tell()
    f.seek(0,2)
    eof_loc = f.tell()
    f.seek(cur_loc, 0)
    if cur_loc >= eof_loc:
        return True
    return False

with open('testfile.txt', 'r+t') as fp:

    while True:
        last_pos = fp.tell()
        line = fp.readline()
        new_line = line.upper()
        fp.seek(last_pos)
        fp.write(new_line)
        print "Read %s, Wrote %s" % (line, new_line)
        if eof(fp):
            break

Somewhat related: Undo a Python file readline() operation so file pointer is back in original state 有点相关: 撤消Python文件readline()操作,使文件指针恢复原始状态

This approach is only justified when your output lines are guaranteed to have the same length, and when, say, the file you're working with is really huge so you have to modify it in place. 只有当您的输出行保证具有相同的长度时,才会证明这种方法是合理的,例如,当您使用的文件非常庞大时,您必须在适当的位置对其进行修改。

In all other cases it would be much easier and more performant to just build the output in memory and write it back at once. 在所有其他情况下,只需在内存中构建输出并立即将其写回,就会更容易,更高效。 Another option is to write to a temporary file, then delete the original and rename the temporary file so it replaces the original file. 另一种选择是写入临时文件,然后删除原始文件并重命名临时文件,以便替换原始文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM