使用Stream-java8替换文件中的文本

使用Stream-java8替换文件中的文本,java,regex,file-io,java-8,java-stream,Java,Regex,File Io,Java 8,Java Stream,我正在尝试编写一个API,用文本文件中不同的字符串替换包含某个子字符串的所有行 我使用Java8流过滤包含给定模式的行。我的文件写入部分有问题 Files.lines(targetFile).filter(line -> line.contains(plainTextPattern)).parallel() .map(line-> line.replaceAll(plainTextPattern, replaceWith)).parallel(); 上面的代码逐行读取文

我正在尝试编写一个API,用文本文件中不同的字符串替换包含某个子字符串的所有行

我使用Java8流过滤包含给定模式的行。我的文件写入部分有问题

Files.lines(targetFile).filter(line -> line.contains(plainTextPattern)).parallel()
      .map(line-> line.replaceAll(plainTextPattern, replaceWith)).parallel();
上面的代码逐行读取文件,过滤与模式匹配的行,并用给定字符串替换,然后返回一个字符串流,其中只有替换的行

我们需要把这些行写回文件。由于一旦管道结束,我们就会丢失流,因此我将以下内容附加到管道:

.forEach(line -> {
try {
            Files.write(targetFile, line.toString().getBytes());
} catch (IOException e) {
  e.printStackTrace();
}
我希望它只将修改过的(因为它在管道中)行写入文件,并保持其他行不变

但它似乎会截断文件中每一行的文件,只保留最后处理的行,并删除管道中所有不匹配的行


关于使用流处理文件,我有什么遗漏吗?

非常抱歉地告诉您,文件不是这样工作的。如果要写入文件的中间部分,需要具有
RandomAccess
;获取一个
文件指针
,查找该指针,然后从那里写入

如果要写入的数据大小等于要覆盖的数据大小,则此选项保持不变。如果不是这样,则必须将文件的尾部复制到临时缓冲区,并将其附加到要写入的文本中


顺便说一句,
IO
绑定任务上的
parallelStreams
通常是个坏主意。

使用
filter
可以从流中消除任何与filter不匹配的内容。(另外,不管怎样,a)您只需要使用一次
parallel
,b)
parallel
对来自I/O源的流不是很有效,c)在您实际尝试过非并行并发现它太慢之前,使用
parallel
几乎从来都不是一个好主意。)

也就是说:如果要执行
replaceAll
,则无需过滤掉与模式匹配的行。您的代码应该如下所示:

try (Stream<String> lines = Files.lines(targetFile)) {
   List<String> replaced = lines
       .map(line-> line.replaceAll(plainTextPattern, replaceWith))
       .collect(Collectors.toList());
   Files.write(targetFile, replaced);
}
try(streamlines=Files.lines(targetFile)){
列表替换=行
.map(line->line.replaceAll(明文模式,replaceWith))
.collect(Collectors.toList());
文件。写入(targetFile,已替换);
}

您可能想要实现一个流,就像Jenkov在这里所做的那样:

这个简单的方法是以
${tokenName}
的形式专门替换令牌


有。

From:“默认情况下,该方法创建新文件或覆盖现有文件。”。有关解决方案,请阅读其余文档。还要记住,您不能简单地更改旧文本文件。您需要用适当的更改创建新的,然后替换它。谢谢!我想到了使用StandardOpenOption.APPEND。但我觉得它并没有意义,因为我不希望它被附加到文件的末尾。它必须更换现有的线路。我又错过什么了吗?我刚试过追加。它将所有内容(包括不匹配的行)追加到文件末尾。。至少这告诉我那些不匹配的线路并没有完全丢失。但是我需要弄清楚如何用新内容重写文件。@AshwiniR试图只替换你想要的文件行,特别是当文件是文本且有换行符时,而不是仅仅替换字节,如果可能的话,这将是一个巨大的混乱。只需做最简单的事情:将整个文件读成行,替换适当的位置,将整个内容写回。所有的评论都非常有用!谢谢大家!!