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);
    }