1

我正在使用 groovy,我试图在特定行更改文本文件,而不循环遍历所有前面的行。有没有办法说明您想要更改的文本文件的行?

例如

文本文件是:

1
2
3
4
5
6

我想说

Line(3) = p

并让它将文本文件更改为:

1
2
p
4
5
6

我不想做一个循环来遍历行来更改值,也就是我不想使用 .eachline {line ->...} 方法。

提前谢谢你,我真的很感激!

4

2 回答 2

2

我认为您不能像这样跳过行和遍历。您可以通过使用 java 中的随机访问文件来跳过,但您应该指定字节数而不是行。

于 2012-07-24T05:50:01.427 回答
1

尝试readLines()在文件文本上使用。它将所有行存储在一个列表中。要更改第 n 行的内容,请更改列表中 n-1 索引处的内容,然后加入列表项。这样的事情会做

//We can call this the DefaultFileHandler

lineNumberToModify = 3
textToInsert = "p"

line( lineNumberToModify, textToInsert )

def line(num , text){
    list = file.readLines()
    list[num - 1]  = text        
    file.setText(list.join("\n"))
}

编辑:对于非常大的文件,最好有一个自定义实现。可能与蒂姆耶茨在对您的问题的评论中所建议的内容相符。上面的 readLines() 可以在不到一秒的时间内轻松处理多达 100000 行文本。所以你可以做这样的事情:

if(file size < 10 MB)
   use DefaultFileHandler()
else
   use CustomFileHandler()


//CustomFileHandler

 - Split the large file into buckets of acceptable size.
 - Ex: Bucket 1(1-100000 lines), Bucket 2(100000-200000 lines), etc.
 - if (lineNumberToModify falls in bucket range)
      insert into line in the bucket

没有硬性规则来定义如何实现 CustomFileHandler,因为它完全取决于用例场景。如果需要对同一个文件多次进行上述操作,可以选择先进行完整的bucket拆分,存储在内存中,然后使用bucket进行后续操作。或者,如果它是一次性操作,您可以避免先操作所有存储桶,而只处理您需要的内容,稍后按需处理其他存储桶。

即使在桶中,您也可以定义自己的智能来加快您的工作。假设你想插入一个有 1-100000 行的桶的 99999 行,你可以充分利用 groovy 的方法和闭包,

file.readLines().reverse()[1] = "some text" 
于 2012-07-24T06:03:51.567 回答