There is a way to partition and process your file content into n
-size chunks using standard Java 8 Stream API. You can use Collectors.groupingBy()
to partition your file content into chunks - you can collect them as a Collection<List<String>>
or you can apply some processing while collecting all lines (e.g. you can join them to a single String).
Take a look at following example:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class ReadFileWithStream {
public static void main(String[] args) throws IOException {
// Path to a file to read
final Path path = Paths.get(ReadFileWithStream.class.getResource("/input.txt").toURI());
final AtomicInteger counter = new AtomicInteger(0);
// Size of a chunk
final int size = 4;
final Collection<List<String>> partitioned = Files.lines(path)
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / size))
.values();
partitioned.forEach(System.out::println);
}
}
My input file contains some numbers (one number at a line), and when I run following code I get something like:
[0, 0, 0, 2]
[0, -3, 2, 0]
[1, -3, -8, 0]
[2, -12, -11, -11]
[-8, -1, -8, 0]
[2, -1, 2, -1]
... and so on
Collectors.groupingBy()
allows me also to use different downstream collector. By default Collectors.toList()
is being used so my result is accumulated into a List<String>
and I get Collection<List<String>>
as a final result.
Let's say I want to read 4-size chunks and I want to sum all numbers in a chunk. In this case I will use Collectors.summingInt()
as my downstream function and the returned result is Collection<Integer>
:
final Collection<Integer> partitioned = Files.lines(path)
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / size, Collectors.summingInt(Integer::valueOf)))
.values();
Output:
2
-1
-10
-32
-17
2
-11
-49
... and so on
And last but not least. Collectors.groupingBy()
returns a map where values are grouped by specific keys. That's why in the end we call Map.values()
to get a collection of the values this contained in this map.
Hope it helps.