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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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.*;
|
||||||
import java.nio.channels.*;
|
import java.nio.channels.*;
|
||||||
import java.nio.channels.spi.*;
|
import java.nio.channels.spi.*;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is defined here rather than in java.nio.channels.Channels
|
* 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)
|
public synchronized int read(byte[] bs, int off, int len)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
Objects.checkFromIndexSize(off, len, bs.length);
|
||||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
if (len == 0)
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
} else if (len == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ByteBuffer bb = ((this.bs == bs)
|
ByteBuffer bb = ((this.bs == bs)
|
||||||
|
@ -119,6 +117,26 @@ public class ChannelInputStream
|
||||||
return 0;
|
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 {
|
public void close() throws IOException {
|
||||||
ch.close();
|
ch.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @test
|
/* @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
|
* @summary Unit test for miscellenous methods in java.nio.file.Files
|
||||||
* @library ..
|
* @library ..
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import static java.nio.file.Files.*;
|
import static java.nio.file.Files.*;
|
||||||
import static java.nio.file.LinkOption.*;
|
import static java.nio.file.LinkOption.*;
|
||||||
|
@ -44,6 +47,7 @@ public class Misc {
|
||||||
testIsSameFile(dir);
|
testIsSameFile(dir);
|
||||||
testFileTypeMethods(dir);
|
testFileTypeMethods(dir);
|
||||||
testAccessMethods(dir);
|
testAccessMethods(dir);
|
||||||
|
testSkip(dir);
|
||||||
} finally {
|
} finally {
|
||||||
TestUtil.removeAll(dir);
|
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) {
|
static void assertTrue(boolean okay) {
|
||||||
if (!okay)
|
if (!okay)
|
||||||
throw new RuntimeException("Assertion Failed");
|
throw new RuntimeException("Assertion Failed");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue