java.lang.IllegalStateException:迭代器已经获得 [英] java.lang.IllegalStateException: Iterator already obtained

查看:840
本文介绍了java.lang.IllegalStateException:迭代器已经获得的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我修改了这段代码,在一个目录中执行了几项任务:

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.

推荐答案


虽然DirectoryStream扩展了Iterable,但它不是通用的Iterable,因为它只支持一个Iterator;调用iterator方法获取第二个或后续迭代器会抛出IllegalStateException。

While DirectoryStream extends Iterable, it is not a general-purpose Iterable as it supports only a single Iterator; invoking the iterator method to obtain a second or subsequent iterator throws IllegalStateException.

Source

Iterable 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:迭代器已经获得的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆