我修改了这段代码,在一个目录中执行了几项任务:
public class HDDSerialNumber
{
public void getHDDSerialNumber() throws IOException
{
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*"))
{
// Get HDD Model
StreamSupport.stream(ds.spliterator(), false)
.map(p -> p.resolve("device/model")).flatMap(wrap(Files::lines))
.forEach(System.out::println);
// Get HDD Vendor
StreamSupport.stream(ds.spliterator(), false)
.map(p -> p.resolve("device/vendor")).flatMap(wrap(Files::lines))
.forEach(System.out::println);
// Get HDD Vendor
StreamSupport.stream(ds.spliterator(), false)
.map(p -> p.resolve("device/state")).flatMap(wrap(Files::lines))
.forEach(System.out::println);
}
}
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);
}
};
}
interface IOFunction<T, R>
{
R apply(T in) throws IOException;
}
}
但是当我运行代码时,我得到了这个错误堆栈:
run:
ST320LT012-9WS14
Exception in thread "main" java.lang.IllegalStateException: Iterator already obtained
at sun.nio.fs.UnixDirectoryStream.iterator(UnixDirectoryStream.java:118)
at sun.nio.fs.UnixSecureDirectoryStream.iterator(UnixSecureDirectoryStream.java:73)
at java.lang.Iterable.spliterator(Iterable.java:101)
at hardware.HDDSerialNumber.getHDDSerialNumber(HDDSerialNumber.java:25)
at hardware.Hardware.main(Hardware.java:12)
Java Result: 1
你能帮我解决一下代码吗?我想已经获得的Iterator在这个例子中只能使用一次,但我不知道如何解决这个问题。
答案 0 :(得分:6)
虽然DirectoryStream扩展了Iterable,但它不是通用的Iterable,因为它只支持一个Iterator;调用iterator方法来获取第二个或后续的迭代器会抛出IllegalStateException。
(Source)
Iterable
(Files.newDirectoryStream
实现DirectoryStream
)返回的Iterable
的迭代器只能使用一次。您可以通过分别为正在创建的3个流中的每个流调用Files.newDirectoryStream
来解决此问题。
不是创建一个DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*");
并在所有3个StreamSupport.stream
调用中使用它,而是创建3个DirectoryStream<Path>
。
示例:
public void getHDDSerialNumber() throws IOException
{
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*"))
{
// Get HDD Model
StreamSupport.stream(ds.spliterator(), false)
.map(p -> p.resolve("device/model")).flatMap(wrap(Files::lines))
.forEach(System.out::println);
}
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*"))
{
// Get HDD Vendor
StreamSupport.stream(ds.spliterator(), false)
.map(p -> p.resolve("device/vendor")).flatMap(wrap(Files::lines))
.forEach(System.out::println);
}
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*"))
{
// Get HDD State
StreamSupport.stream(ds.spliterator(), false)
.map(p -> p.resolve("device/state")).flatMap(wrap(Files::lines))
.forEach(System.out::println);
}
}
编辑:
如果你想处理一个在不中断程序执行的情况下不存在的文件的情况,请抓住在这种情况下抛出的异常。
例如:
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*"))
{
// Get HDD State
StreamSupport.stream(ds.spliterator(), false)
.map(p -> p.resolve("device/state"))
.flatMap(wrap(path - > try {
return Files.lines(path);
} catch (IOException ioEx) {
return Stream.empty();
}))
.forEach(System.out::println);
}
这将捕获异常并返回一个空的Stream。