Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace text in a file using Stream- Java 8

I'm trying to write an API to replace all the lines containing a certain substring with a different string in a text file.

I’m using Java 8 stream to filter the lines which contains the given pattern. I’m having problem with the file write part.

Files.lines(targetFile).filter(line -> line.contains(plainTextPattern)).parallel()
      .map(line-> line.replaceAll(plainTextPattern, replaceWith)).parallel();

Above code reads the file line-wise, filters the lines that match the pattern and replaces with the give string and gives back a stream of strings which has only the replaced lines.

We need to write these lines back to file. Since we lose the stream once the pipeline ends, I appended the following to the pipeline:

.forEach(line -> {
try {
            Files.write(targetFile, line.toString().getBytes());
} catch (IOException e) {
  e.printStackTrace();
}

I was hoping it would write to the file only the modified (since it is in the pipeline) line and keep the other lines untouched.

But it seems to truncate the file for each line in the file and keep only the last processed line and deletes all the lines that were not matched in the pipeline.

Is there something I’m missing about handling files using streams?

like image 635
A.R.K.S Avatar asked Feb 05 '16 22:02

A.R.K.S


People also ask

How do I replace a string in a file in Java?

Java: Replace Strings in Streams, Arrays, Files etc. Sometimes you need to replace strings or tokens in streams, arrays, files, or large strings. You could use the String.replace() method, but for large amounts of data, and high number of replacements, this performs badly.

How to read file as stream in Java 8?

In Java 8, you can use Files.lines to read file as Stream. 1. Java 8 Read File + Stream 2. Java 8 Read File + Stream + Extra This example shows you how to use Stream to filter content, convert the entire content to upper case and return it as a List. 3. BufferedReader + Stream

How to read a file line by line in Java 8?

Java 8 Stream – Read a file line by line. 1 1. Java 8 Read File + Stream. TestReadFile.java package com.mkyong.java8; import java.io.IOException; import java.nio.file.Files; import java.nio.file. 2 2. Java 8 Read File + Stream + Extra. 3 3. BufferedReader + Stream. 4 4. Classic BufferedReader And Scanner.

How to modify a text variable in a stream?

Since you can’t use the stream to modify the text variable you have to coerce the operation into one Function which you can apply to the text to get the final result:


1 Answers

Using filter eliminates anything that doesn't match the filter from the stream. (Additionally, for what it's worth, a) you only need to use parallel once, b) parallel isn't that effective on streams coming from I/O sources, c) it's almost never a good idea to use parallel until you've actually tried it non-parallel and found it too slow.)

That said: there's no need to filter out the lines that match the pattern if you're going to do a replaceAll. Your code should look like this:

try (Stream<String> lines = Files.lines(targetFile)) {
   List<String> replaced = lines
       .map(line-> line.replaceAll(plainTextPattern, replaceWith))
       .collect(Collectors.toList());
   Files.write(targetFile, replaced);
}
like image 171
Louis Wasserman Avatar answered Oct 20 '22 00:10

Louis Wasserman