Repository: commons-compress Updated Branches: refs/heads/COMPRESS-449 [created] eafb70805
COMPRESS-449 try to deal with cases where skip throws Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/eafb7080 Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/eafb7080 Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/eafb7080 Branch: refs/heads/COMPRESS-449 Commit: eafb708059b732712a431449172de45e988d932b Parents: 97867f6 Author: Stefan Bodewig <bode...@apache.org> Authored: Wed Apr 25 18:04:03 2018 +0200 Committer: Stefan Bodewig <bode...@apache.org> Committed: Wed Apr 25 18:04:03 2018 +0200 ---------------------------------------------------------------------- .../apache/commons/compress/utils/IOUtils.java | 26 ++++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/eafb7080/src/main/java/org/apache/commons/compress/utils/IOUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/utils/IOUtils.java b/src/main/java/org/apache/commons/compress/utils/IOUtils.java index c7e0e80..1902de3 100644 --- a/src/main/java/org/apache/commons/compress/utils/IOUtils.java +++ b/src/main/java/org/apache/commons/compress/utils/IOUtils.java @@ -102,12 +102,28 @@ public final class IOUtils { */ public static long skip(final InputStream input, long numToSkip) throws IOException { final long available = numToSkip; - while (numToSkip > 0) { - final long skipped = input.skip(numToSkip); - if (skipped == 0) { - break; + // skip may throw an IOException for streams that contain an unseekable stream somewhere in the chain, see + // https://issues.apache.org/jira/browse/COMPRESS-449 not using skip but only using read would be an option but + // a costly one. + // the heuristics here are: + // * if the stream doesn't support mark, skip will likely use read, so we can do so as well + // * if it does and it throws an exception during skip we can try to rewind and fall back to read. If the + // IOException has been genuine, read will hopefully throw one as well + if (input.markSupported()) { + while (numToSkip > 0) { + int skipNow = (int) Math.min(numToSkip, (long) Integer.MAX_VALUE); + input.mark(skipNow); + try { + final long skipped = input.skip(skipNow); + if (skipped <= 0) { + break; + } + numToSkip -= skipped; + } catch (IOException ex) { + input.reset(); + break; + } } - numToSkip -= skipped; } while (numToSkip > 0) {