java.lang.IllegalStateException:已获得迭代器
我修改了此代码以在一个目录中执行多个任务:java.lang.IllegalStateException:已获得迭代器,java,java-8,Java,Java 8,我修改了此代码以在一个目录中执行多个任务: public class HDDSerialNumber { public void getHDDSerialNumber() throws IOException { try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get("/sys/block"), "sd*")) { // Get H
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;
}
}
你能帮我修一下密码吗?我想在这个例子中,已经获得的迭代器只能使用一次,但我不知道如何解决这个问题
虽然DirectoryStream扩展了Iterable,但它不是一个通用Iterable,因为它只支持一个迭代器;调用迭代器方法以获取第二个或后续迭代器会引发IllegalStateException
()
由文件返回的Iterable
的迭代器。newDirectoryStream
(DirectoryStream
实现Iterable
)只能使用一次。您可以通过分别为正在创建的3个流中的每个流调用Files.newDirectoryStream
来解决此问题
而不是创建一个DirectoryStream ds=Files.newDirectoryStream(path.get(“/sys/block”),“sd*”
并在所有3个StreamSupport.stream调用中使用它,创建3个DirectoryStream
例如:
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);
}
}
public void getHDDSerialNumber()引发IOException
{
try(DirectoryStream ds=Files.newDirectoryStream(path.get(“/sys/block”),“sd*”)
{
//获取硬盘型号
StreamSupport.stream(ds.spliterator(),false)
.map(p->p.resolve(“设备/模型”)).flatMap(wrap(文件::行))
.forEach(System.out::println);
}
try(DirectoryStream ds=Files.newDirectoryStream(path.get(“/sys/block”),“sd*”)
{
//获取硬盘供应商
StreamSupport.stream(ds.spliterator(),false)
.map(p->p.resolve(“设备/供应商”)).flatMap(wrap(文件::行))
.forEach(System.out::println);
}
try(DirectoryStream ds=Files.newDirectoryStream(path.get(“/sys/block”),“sd*”)
{
//获取硬盘状态
StreamSupport.stream(ds.spliterator(),false)
.map(p->p.resolve(“设备/状态”)).flatMap(wrap(文件::行))
.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);
}
try(DirectoryStream ds=Files.newDirectoryStream(path.get(“/sys/block”),“sd*”)
{
//获取硬盘状态
StreamSupport.stream(ds.spliterator(),false)
.map(p->p.resolve(“设备/状态”))
.flatMap(换行(路径->尝试{
返回文件。行(路径);
}捕获(IOException ioEx){
返回Stream.empty();
}))
.forEach(System.out::println);
}
这将捕获异常并返回空流。非常好!我可以再问一个问题吗?如果找不到文件,我会得到java.nio.file.NoSuchFileException如何在不中断程序执行的情况下跳过该文件?@PeterPenzov我相信您可以用try块包装调用导致异常并捕获异常。我不确定异常抛出的位置。我假设在flatMap
的map
中。例如,如果它被抛出map
,则执行.map(p->尝试{p.resolve(“…”);}catch(NoSuchFileException ex){}
。
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);
}