我可以在需要行数和追加内容时避免处理文件两次吗?

2 投票
4 回答
549 浏览
提问于 2025-04-15 12:25

我正在分阶段地将一个文件写入磁盘。在写文件的过程中,我需要知道我写入的行号,以便建立一个索引。现在这个文件有1200万行,所以我需要实时建立索引。我分了四个步骤,针对我索引的值进行了四组处理。根据我在其他地方找到的一些例子,我决定在开始写之前先获取文件的行数,这样我就可以用这个数字来继续建立我的索引。

但是我遇到了一个问题,理论上我不知道我是在往文件中添加第一部分还是最后一部分,所以我想通过获取当前的文件大小来解决这个问题:

myFile=open(r'C:\NEWMASTERLIST\FULLLIST.txt','a')
try:
    num_lines=sum(1 for line in myFile)
except IOError:
    num_lines=0

当我这样做时,结果总是0——即使myFile存在并且行数大于0。

如果我这样做:

myFile=open(r'C:\NEWMASTERLIST\FULLLIST.txt')
try:
    num_lines=sum(1 for line in myFile)
except IOError:
    num_lines=0

当myFile存在时,我能得到正确的值。但是如果myFile不存在,且我在第一次循环中,就会收到错误信息。

在我写这个问题的时候,我意识到每次文件存在时num_lines=0的原因是因为文件是以追加模式打开的,所以文件是从最后一行开始的,现在在等待新行的写入。所以这个问题可以通过以下方式解决:

try:
    myFile=open(r'C:\NEWMASTERLIST\FULLLIST.txt')
    num_lines=sum(1 for line in myFile)

except IOError:
    num_lines=0

我的问题是,这个过程是否可以用其他方式来实现。我之所以问这个,是因为我现在必须关闭myFile,然后再重新打开它以进行追加:

也就是说,既然我已经有了文件中数据的结束索引号,我现在需要做的工作是:

myFile.close()
myFile=open(r'C:\NEWMASTERLIST\FULLLIST.txt','a')

现在,这里可能是我学到东西的地方——既然我必须打开文件两次,也许获取起始索引(num_lines)应该放到一个函数里去做。

def getNumbLines(myFileRef):
    try:
        myFile=open(myFileRef)
        num_lines=sum(1 for line in myFile)
        myFile.close()
    except IOError:
        num_lines=0
    return num_lines

如果我不需要打开/处理文件两次,那样会更简洁。

根据Eric Wendelin的回答,我可以直接这样做:

myFile=open(r'C:\NEWMASTERLIST\FULLLIST.txt','a+')
num_lines=sum(1 for line in myFile)

谢谢!

4 个回答

0

虽然来得有点晚,但对于文件存在的问题,为什么不试试下面这个(伪代码)呢:

If FileExists(C:\NEWMASTERLIST\FULLLIST.txt') then
begin
  Open file etc 
  Calc numlines etc
end
else
  Create new file etc
  NumLines := 0;
end;
0

我猜你是在写文件,对吧?那为什么不单独记录一下你已经写了多少行呢?我觉得这样做很浪费,因为你每次都要一行一行地读取整个文件才能知道行号。

4

你可以同时打开一个文件进行读取和写入:

myFile=open(r'C:\NEWMASTERLIST\FULLLIST.txt','r+')

试试看这个。

更新:哦,我错了,因为这个文件可能不存在。用'a+'代替'r+'。

撰写回答