I want to remove lines from a CSV file which contain the wrong date. In the process the CSV file should retain the header line. All this I want to perform using java 8 streams.
At first I cam up with this:
try (Stream<String> linesUnfiltered = Files.lines(f.toPath(), StandardCharsets.UTF_8)) {
Stream<String> firstLine = linesUnfiltered.limit(1);
Stream<String> linesFiltered = linesUnfiltered
.filter(e -> e.contains(sdfFileContent.format(fileDate)));
Stream<String> result = Stream.concat(firstLine, linesFiltered);
Files.write(f.toPath(), (Iterable<String>) result::iterator);
}
But this throws the exception java.lang.IllegalStateException: stream has already been operated upon or closed
because linesUnfiltered
is reused. The suggestion on the web is to use a Supplier<Stream<String>>
, but my understanding is that the supplier would read the file for each supplier.get()
call, which is not very efficient.
And thats why I am asking if there is another way which is more efficient that this? I am pretty certain that it should be possible to perform the two operations on the same stream...
EDIT:
It is NOT a duplicate as the first item should not be removed. It should only be excluded from the filtering process but still be available in the result stream