mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8227080: (fs) Files.newInputStream(...).skip(n) is slow
Reviewed-by: sbordet, rriggs, fweimer
This commit is contained in:
parent
5b24465467
commit
c6c82dd736
2 changed files with 61 additions and 7 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -29,7 +29,7 @@ import java.io.*;
|
|||
import java.nio.*;
|
||||
import java.nio.channels.*;
|
||||
import java.nio.channels.spi.*;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This class is defined here rather than in java.nio.channels.Channels
|
||||
|
@ -87,10 +87,8 @@ public class ChannelInputStream
|
|||
public synchronized int read(byte[] bs, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0)
|
||||
Objects.checkFromIndexSize(off, len, bs.length);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
ByteBuffer bb = ((this.bs == bs)
|
||||
|
@ -119,6 +117,26 @@ public class ChannelInputStream
|
|||
return 0;
|
||||
}
|
||||
|
||||
public synchronized long skip(long n) throws IOException {
|
||||
// special case where the channel is to a file
|
||||
if (ch instanceof SeekableByteChannel && n > 0) {
|
||||
SeekableByteChannel sbc = (SeekableByteChannel)ch;
|
||||
try {
|
||||
long pos = sbc.position();
|
||||
long size = sbc.size();
|
||||
if (pos >= size) {
|
||||
return 0L;
|
||||
}
|
||||
n = Math.min(n, size - pos);
|
||||
sbc.position(pos + n);
|
||||
return sbc.position() - pos;
|
||||
} catch (ClosedChannelException cce) {
|
||||
throw new IOException(cce);
|
||||
}
|
||||
}
|
||||
return super.skip(n);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
ch.close();
|
||||
}
|
||||
|
|
|
@ -22,11 +22,14 @@
|
|||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4313887 6838333 8005566 8032220 8215467
|
||||
* @bug 4313887 6838333 8005566 8032220 8215467 8227080
|
||||
* @summary Unit test for miscellenous methods in java.nio.file.Files
|
||||
* @library ..
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.file.*;
|
||||
import static java.nio.file.Files.*;
|
||||
import static java.nio.file.LinkOption.*;
|
||||
|
@ -44,6 +47,7 @@ public class Misc {
|
|||
testIsSameFile(dir);
|
||||
testFileTypeMethods(dir);
|
||||
testAccessMethods(dir);
|
||||
testSkip(dir);
|
||||
} finally {
|
||||
TestUtil.removeAll(dir);
|
||||
}
|
||||
|
@ -372,6 +376,38 @@ public class Misc {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Files.newInputStream(Path).skip().
|
||||
*/
|
||||
static void testSkip(Path tmpdir) throws IOException {
|
||||
Path file = createFile(tmpdir.resolve("foo"));
|
||||
try (OutputStream out = Files.newOutputStream(file)) {
|
||||
byte[] blah = new byte[8192];
|
||||
Arrays.fill(blah, (byte)42);
|
||||
out.write(blah);
|
||||
out.close();
|
||||
try (InputStream in = Files.newInputStream(file)) {
|
||||
assertTrue(in.skip(-1) == 0);
|
||||
assertTrue(in.skip(0) == 0);
|
||||
assertTrue(in.skip(blah.length/4) == blah.length/4);
|
||||
assertTrue(in.skip(blah.length/2) == blah.length/2);
|
||||
assertTrue(in.skip(Long.MAX_VALUE) == blah.length/4);
|
||||
in.close();
|
||||
try {
|
||||
long n = in.skip(1);
|
||||
throw new RuntimeException("skip() did not fail");
|
||||
} catch (IOException ioe) {
|
||||
if (!(ioe.getCause() instanceof ClosedChannelException)) {
|
||||
throw new RuntimeException
|
||||
("IOException not caused by ClosedChannelException");
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
delete(file);
|
||||
}
|
||||
}
|
||||
|
||||
static void assertTrue(boolean okay) {
|
||||
if (!okay)
|
||||
throw new RuntimeException("Assertion Failed");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue