read() 函数会影响文件内容吗?

Does read() function affect the file content?

我有一个固定格式的 .txt 文件:

Tudo Bom;Static and Ben El Tavori;5:13;
I Gotta Feeling;The Black Eyed Peas;4:05;
Instrumental;Unknown;4:15;
Paradise;Coldplay;4:23;
Where is the love?;The Black Eyed Peas;4:13;

我正在尝试用新名称替换第三行中的歌曲名称。

我编写了一个名为 my_mp4_playlist 的函数,它有两个参数: 第一个是文件路径(字符串),第二个是新歌名(字符串)。

我试图首先使用 read() 函数获取文件内容,然后将文件行循环到第三行并用 ";".

拆分行

我的问题是,当我使用 read() 功能时,没有任何东西可以拆分,当我不阅读时,拆分工作正常。

代码(尚未完成)如下所示:

def my_mp4_playlist(file_path, new_song):
    with open(file_path, "r+") as f:  # we using r+ for reading and writing and not overriding ALL text in the file
        file_source = f.read()
        third_line_list = []
        for i, line in enumerate(f, 0):
            if i == 2:
                print(line.split(";"))
                third_line_list = line.split(";")
                break    

打印语句的输出什么也没有。 但是如果我评论 f.read() 行,输出是:

['Instrumental', 'Unknown', '4:15', '\n']

为什么会这样?我想以更笼统的方式了解问题,而不是针对我的问题的具体解决方案。

https://pynative.com/python-file-seek/

在大多数编程语言中读取文件时,文件对象维护一个 'cursor'(也称为 'pointer')来跟踪文件中已经读取的部分以及从哪里开始读取读取后续读取请求。此游标从文件的第一个字节开始,向前移动,直到到达文件末尾。

例如,当您逐行读取文件时,文件对象从光标的当前位置开始,读取该行,然后将光标前进到它刚读取的行的末尾。它知道当光标到达文件末尾时停止阅读。

因此,在您初次调用 f.read() 时,您正在读取整个文件,因此光标位于文件末尾。在随后调用 enumerate (f,0) 时,由于光标位于文件末尾,因此文件中没有任何内容可读,因此实际上跳过了循环。

当你注释掉f.read()时,由于你还没有读取enumerate (f,0)之前的文件,文件光标停留在文件的开头,所以这就是你注释时循环起作用的原因输出 f.read()

如果你需要保留file_source = f.read()file_source看起来没用,所以我不确定它的用途)那么你需要将文件光标重置到文件开头在下一次阅读之前。您可以使用 f.seek(0) 执行此操作,这会将光标放回文件中的第 0 个字节。

或者,由于文件的全部内容现在都在 file_source 中,您不再需要直接从文件中读取。

当您打开文件时,当前读取位置设置为0。这里的问题是,当您使用read() 方法读取文件的全部内容后,读取位置移动到文件末尾。 因此,当您尝试在此枚举器中再次读取文件内容时,没有任何内容可读,因为读取位置已经在文件末尾。

如果您对 read() 方法进行注释,那么在调用枚举器时,读取位置仍将为 0,因此有内容可读。

要解决这个问题,您可以在调用枚举器之前使用 seek() 方法重置读取位置,并将其设置为位置 0。

f.seek(0)
for i, line in enumerate(f, 0):

您还可以使用枚举器中的 read() 方法读取的整个文件内容,而不是从文件中读取。这是更可取的解决方案,因为您不需要再次从磁盘读取文件,而是重用内存中已有的内容。像这样的东西应该这样做:

for i, line in enumerate(file_source.splitlines(), 0):