簡體   English   中英

java.lang.IllegalStateException:已經獲得迭代器

[英]java.lang.IllegalStateException: Iterator already obtained

我修改了此代碼,以在一個目錄中執行多個任務:

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只能使用一次,但是我不知道如何解決這個問題。

雖然DirectoryStream擴展了Iterable,但它不是通用的Iterable,因為它僅支持單個Iterator。 調用迭代器方法以獲得第二個或后續迭代器,則拋出IllegalStateException。

來源

Files.newDirectoryStreamDirectoryStream實現Iterable )返回的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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM