# HG changeset patch # User alanb # Date 1369819451 -3600 # Node ID 8bbdf55ba9d4b391adf3f9dd2f5de5702d6f8254 # Parent 1703e6521c972ecee7240245e2b356feb4f31822 8014928: (fs) Files.readAllBytes() copies content to new array when content completely read Reviewed-by: martin diff -r 1703e6521c97 -r 8bbdf55ba9d4 jdk/src/share/classes/java/nio/file/Files.java --- a/jdk/src/share/classes/java/nio/file/Files.java Wed May 29 09:42:39 2013 +0200 +++ b/jdk/src/share/classes/java/nio/file/Files.java Wed May 29 10:24:11 2013 +0100 @@ -25,9 +25,11 @@ package java.nio.file; +import java.nio.ByteBuffer; import java.nio.file.attribute.*; import java.nio.file.spi.FileSystemProvider; import java.nio.file.spi.FileTypeDetector; +import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; import java.io.Closeable; import java.io.InputStream; @@ -2945,40 +2947,6 @@ } /** - * Read all the bytes from an input stream. The {@code initialSize} - * parameter indicates the initial size of the byte[] to allocate. - */ - private static byte[] read(InputStream source, int initialSize) - throws IOException - { - int capacity = initialSize; - byte[] buf = new byte[capacity]; - int nread = 0; - int rem = buf.length; - int n; - // read to EOF which may read more or less than initialSize (eg: file - // is truncated while we are reading) - while ((n = source.read(buf, nread, rem)) > 0) { - nread += n; - rem -= n; - assert rem >= 0; - if (rem == 0) { - // need larger buffer - int newCapacity = capacity << 1; - if (newCapacity < 0) { - if (capacity == Integer.MAX_VALUE) - throw new OutOfMemoryError("Required array size too large"); - newCapacity = Integer.MAX_VALUE; - } - rem = newCapacity - capacity; - buf = Arrays.copyOf(buf, newCapacity); - capacity = newCapacity; - } - } - return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); - } - - /** * Read all the bytes from a file. The method ensures that the file is * closed when all bytes have been read or an I/O error, or other runtime * exception, is thrown. @@ -3003,12 +2971,22 @@ * method is invoked to check read access to the file. */ public static byte[] readAllBytes(Path path) throws IOException { - long size = size(path); - if (size > (long)Integer.MAX_VALUE) - throw new OutOfMemoryError("Required array size too large"); + try (FileChannel fc = FileChannel.open(path)) { + long size = fc.size(); + if (size > (long)Integer.MAX_VALUE) + throw new OutOfMemoryError("Required array size too large"); - try (InputStream in = newInputStream(path)) { - return read(in, (int)size); + byte[] arr = new byte[(int)size]; + ByteBuffer bb = ByteBuffer.wrap(arr); + while (bb.hasRemaining()) { + if (fc.read(bb) < 0) { + // truncated + break; + } + } + + int nread = bb.position(); + return (nread == size) ? arr : Arrays.copyOf(arr, nread); } }