0

我目前正在编写一个需要在文本文件中读取和写入行的游戏。我想知道是否有办法读取文本文件中的特定行(即文本文件中的第一行)。另外,有没有办法在特定位置写一行(即更改文件中的第一行,写几行,然后再次更改第一行)?我知道我们可以通过调用顺序读取行:

f.readline()

编辑:根据响应,如果特定行的长度不同,显然无法读取它们。我只从事大型团队项目的一小部分工作,要改变我存储数据的方式将意味着很多工作。

但是有没有一种方法可以专门更改文件的第一行?我知道打电话:

f.write('text')

将某些内容写入文件,但它将行写入文件末尾而不是开头。有没有办法让我在开头专门重写文本?

4

2 回答 2

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 上仅替换第一行。

测试数据

this line has n characters
this line also has n characters

测试.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()
于 2012-05-25T16:03:26.483 回答
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)

约翰真的是一个 1337 游戏玩家。但是,此时,您也可以删除一个用户,更改 Rudolf 的分数或更改 Peter 的名称,......无论如何,修改后,您可以简单地将新数据写回磁盘:

with open("gamedata.dat", "w") as f:
    f.write(json.dumps(gamedata).encode("utf-8"))

关键是您在运行时在适当的容器类型中管理(创建/修改/删除)数据。将数据写入磁盘时,您会写入整个数据集以保存游戏的当前状态。

于 2012-05-25T16:11:46.703 回答