问题描述
我修改了这段代码,在一个目录中执行了几项任务:
I modified this code to do several tasks in one directory:
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;
}
}
但是当我运行代码时,我得到了这个错误堆栈:
But when I run the code I get this error stack:
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
你能帮我修改代码吗?我想已经获得的迭代器必须在这个例子中只使用一次,但我不知道如何解决这个问题。
Can you help me to fix the code, please? I suppose that Iterator already obtained must be used only once in this example but I don't have idea how to fix this.
推荐答案
()
Iterable $ c $的迭代器c>由
Files.newDirectoryStream
返回( DirectoryStream
实现 Iterable
)只能使用一次。你可以通过分别为你正在创建的3个流中的每个流调用 Files.newDirectoryStream
来解决它。
The iterator of the Iterable
returned by Files.newDirectoryStream
(DirectoryStream
implements Iterable
) can only be used once. You can solve it by calling Files.newDirectoryStream
separately for each of the 3 streams you are creating.
而不是创建一个 DirectoryStream< Path> ds = Files.newDirectoryStream(Paths.get(/ sys / block),sd *);
并在所有3 StreamSupport.stream中使用它
来电,创建3 DirectoryStream<路径>
。
Instead of creating one DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*");
and using it in all 3 StreamSupport.stream
calls, create 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);
}
}
编辑:
如果要在不中断程序执行的情况下处理不存在的文件的情况,请捕获在这种情况下抛出的异常。
If you want to handle the case of a file that doesn't exist without interrupting the program execution, catch the exception thrown in that case.
例如:
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);
}
这将捕获异常并返回一个空流。
This would catch the exception and return an empty Stream.
这篇关于java.lang.IllegalStateException:迭代器已经获得的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!