Here is an example of how to do this using Java 8 features:
Function<Path,byte[]> uncheckedRead = p -> {
try { return Files.readAllBytes(p); }
catch(IOException ex) { throw new UncheckedIOException(ex); }
};
try(Stream<Path> s=Files.find(Paths.get("/sys/block"), 1,
(p,a)->p.getName(p.getNameCount()-1).toString().startsWith("sd"))) {
s.map(p->p.resolve("device/model")).map(uncheckedRead).map(String::new)
.forEach(System.out::println);
}
This is an example that strives for compactness and working stand-alone. For real applications, it’s likely that you would do it a bit differently. The task of using an IO operation as a Function
which doesn’t allow checked exception is quite common so you might have a wrapper function like:
interface IOFunction<T,R> {
R apply(T in) throws IOException;
}
static <T,R> Function<T,R> wrap(IOFunction<T,R> f) {
return t-> { try { return f.apply(t); }
catch(IOException ex) { throw new UncheckedIOException(ex); }
};
}
Then you can use
try(Stream<Path> s=Files.find(Paths.get("/sys/block"), 1,
(p,a)->p.getName(p.getNameCount()-1).toString().startsWith("sd"))) {
s.map(p->p.resolve("device/model")).map(wrap(Files::readAllBytes))
.map(String::new).forEach(System.out::println);
}
But maybe you’d use newDirectoryStream
instead even if the returned DirectoryStream
is not a Stream
and hence requires a manual Stream
creation as this method allows passing a glob pattern like "sd*"
:
try(DirectoryStream<Path> ds
=Files.newDirectoryStream(Paths.get("/sys/block"), "sd*")) {
StreamSupport.stream(ds.spliterator(), false)
.map(p->p.resolve("device/model")).map(wrap(Files::readAllBytes))
.map(String::new).forEach(System.out::println);
}
Finally, the option to process the files as stream of lines should be mentioned:
try(DirectoryStream<Path> ds
=Files.newDirectoryStream(Paths.get("/sys/block"), "sd*")) {
StreamSupport.stream(ds.spliterator(), false)
.map(p->p.resolve("device/model")).flatMap(wrap(Files::lines))
.forEach(System.out::println);
}