我目前正在编写一款需要在文本文件中读取和写入行的游戏。我想知道是否有办法读取文本文件中的特定行(即文本文件中的第一行)。另外,有没有办法在特定位置写一行(即更改文件中的第一行,写几行其他行,然后再次更改第一行)?我知道我们可以通过调用来顺序读取行:
f.readline()
编辑:根据回复,显然如果长度不同,则无法读取特定行。我只是在一个大型团队项目的一小部分工作,并改变我存储数据的方式意味着很多工作。
但有没有一种方法可以专门更改文件的第一行?我知道打电话:
f.write('text')
将某些内容写入文件,但它将该行写在文件末尾而不是开头。有没有办法让我在开始时专门重写文本?
答案 0 :(得分:1)
如果保证所有行的长度相同,则可以使用f.seek(N)
将文件指针定位在第N个字节(其中N是LINESIZE * line_number),然后f.read(LINESIZE)
。否则,我不知道在普通的ASCII文件中做任何事情(我认为这就是你所问的)。
当然,您可以在文件的标题中存储某种记录信息,并首先读取该信息,以便让您知道文件中的位置 - 但此时您最好使用一些外部库已经完成了所有这些工作。
除非您的文本文件非常大,否则您始终可以将每行存储在列表中:
with open('textfile','r') as f:
lines=[L[:-1] for L in f.readlines()]
(注意我已经脱掉换行线,所以你不必记得把它保留下来)
然后,您可以通过添加条目,删除条目,更改条目等来操作列表。 在一天结束时,您可以将列表写回文本文件:
with open('textfile','w') as f:
f.write('\n'.join(lines))
这是一个小测试,对我来说在OS-X上只能替换第一行。
TEST.DAT
this line has n characters
this line also has n characters
test.py
#First, I get the length of the first line -- if you already know it, skip this block
f=open('test.dat','r')
l=f.readline()
linelen=len(l)-1
f.close()
#apparently mode='a+' doesn't work on all systems :( so I use 'r+' instead
f=open('test.dat','r+')
f.seek(0)
f.write('a'*linelen+'\n') #'a'*linelen = 'aaaaaaaaa...'
f.close()
答案 1 :(得分:0)
现在,以优化的方式在文件中跳转是管理大文件的高性能应用程序的任务。
您确定您的软件项目需要在运行时读取/写入文件中的随机位置吗?我认为你应该考虑改变整个方法:
如果数据很小,您可以在运行时在适当的容器格式(例如列表或字典)中保存/修改/生成数据,然后立即完全写入(在更改时,或仅在您的程序中)退出)。您可以考虑查看简单的数据库。此外,还有很好的数据交换格式,如JSON,如果您的数据在运行时存储在字典中,这将是理想的格式。
一个例子,使概念更清晰。假设您已将数据写入gamedata.dat
:
[{"playtime": 25, "score": 13, "name": "rudolf"}, {"playtime": 300, "score": 1, "name": "peter"}]
这是utf-8编码和JSON格式的数据。在Python游戏运行期间读取文件:
with open("gamedata.dat") as f:
s = f.read().decode("utf-8")
将数据转换为Python类型:
gamedata = json.loads(s)
修改数据(添加新用户):
user = {"name": "john", "score": 1337, "playtime": 1}
gamedata.append(user)
John真的是一名1337游戏玩家。但是,此时,您还可以删除用户,更改Rudolf的分数或更改Peter的名称,...无论如何,在修改之后,您只需将新数据写回磁盘:
with open("gamedata.dat", "w") as f:
f.write(json.dumps(gamedata).encode("utf-8"))
重点是您在运行时在适当的容器类型中管理(创建/修改/删除)数据。将数据写入磁盘时,您可以编写整个数据集以保存游戏的当前状态。