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) {

Reply via email to