編輯:這似乎不可能,請參閱https://bugs.openjdk.java.net/browse/JDK-8039910。在Java 8流中捕獲UncheckedIOException
我有一個幫助類,它提供了一個Stream<Path>
。此代碼只是包裝Files.walk
和排序輸出:
public Stream<Path> getPaths(Path path) {
return Files.walk(path, FOLLOW_LINKS).sorted();
}
作爲符號鏈接,接着,在文件系統(例如一個符號鏈接x -> .
)在Files.walk
使用的代碼循環的情況下,將引發UncheckedIOException
包裹的FileSystemLoopException
一個實例。
在我的代碼中,我想捕獲這些異常,例如,只記錄一條有用的消息。生成的流可能/應該只是在發生這種情況時立即停止提供條目。
我試着將.map(this::catchException)
和.peek(this::catchException)
添加到我的代碼中,但是在這個階段沒有發現異常。
Path checkException(Path path) {
try {
logger.info("path.toString() {}", path.toString());
return path;
} catch (UncheckedIOException exception) {
logger.error("YEAH");
return null;
}
}
如何,如果在所有我能趕上在我的代碼的UncheckedIOException
釋放出Stream<Path>
,使路徑的消費者並沒有遇到這個異常?
作爲一個例子,下面的代碼不應該遇到異常:
java.io.UncheckedIOException: java.nio.file.FileSystemLoopException: /tmp/junit5844257414812733938/selfloop
at java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:88)
at java.nio.file.FileTreeIterator.hasNext(FileTreeIterator.java:104)
at java.util.Iterator.forEachRemaining(Iterator.java:115)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at ...
:
List<Path> paths = getPaths().collect(toList());
眼下,異常是由代碼調用collect
(我能趕上有例外)觸發
編輯:我提供了一個簡單的JUnit測試類。在這個問題中,我要求你通過修改provideStream
中的代碼來修復測試。
package somewhere;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.fail;
public class StreamTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void test() throws Exception {
Path rootPath = Paths.get(temporaryFolder.getRoot().getPath());
createSelfloop();
Stream<Path> stream = provideStream(rootPath);
assertThat(stream.collect(Collectors.toList()), is(not(nullValue())));
}
private Stream<Path> provideStream(Path rootPath) throws IOException {
return Files.walk(rootPath, FOLLOW_LINKS).sorted();
}
private void createSelfloop() throws IOException {
String root = temporaryFolder.getRoot().getPath();
try {
Path symlink = Paths.get(root, "selfloop");
Path target = Paths.get(root);
Files.createSymbolicLink(symlink, target);
} catch (UnsupportedOperationException x) {
// Some file systems do not support symbolic links
fail();
}
}
}
貌似重複,以http://stackoverflow.com/q/22867286/4856258。簡而言之:你無法使用'Files.walk'工作,你必須爲此編寫完全獨立的方法或使用第三方庫。 –
我把這個方法放在completablefuture.suppltasync上,並添加excepcetionaly來捕獲異常? – gaston
我不明白你在說什麼,@ gaston。 –