From: aph Date: Thu, 10 Mar 2005 15:29:15 +0000 (+0000) Subject: 2005-03-09 Andrew Haley X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=c7170b512880b20295e4465b47396f204ffc5e4c;hp=e2704f585052faa726100494c24d27eb87b07d72 2005-03-09 Andrew Haley * gnu/java/nio/channels/FileChannelImpl.java (smallTransferFrom): New. (smallTransferTo): New. (transferFrom): Loop around smallTransferFrom, copying pageSize bytes each time. (transferTo): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96240 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libjava/ChangeLog b/libjava/ChangeLog index e55087ceddb..f62317fe454 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,12 @@ +2005-03-09 Andrew Haley + + * gnu/java/nio/channels/FileChannelImpl.java (smallTransferFrom): + New. + (smallTransferTo): New. + (transferFrom): Loop around smallTransferFrom, copying pageSize + bytes each time. + (transferTo): Likewise. + 2005-03-09 David Daney PR libgcj/20389 diff --git a/libjava/gnu/java/nio/channels/FileChannelImpl.java b/libjava/gnu/java/nio/channels/FileChannelImpl.java index 887d1dcc396..e5b02e9fdb3 100644 --- a/libjava/gnu/java/nio/channels/FileChannelImpl.java +++ b/libjava/gnu/java/nio/channels/FileChannelImpl.java @@ -282,7 +282,30 @@ public final class FileChannelImpl extends FileChannel throw new ClosedChannelException (); } - public long transferTo (long position, long count, WritableByteChannel target) + // like transferTo, but with a count of less than 2Gbytes + private int smallTransferTo (long position, int count, + WritableByteChannel target) + throws IOException + { + ByteBuffer buffer; + try + { + // Try to use a mapped buffer if we can. If this fails for + // any reason we'll fall back to using a ByteBuffer. + buffer = map (MapMode.READ_ONLY, position, count); + } + catch (IOException e) + { + buffer = ByteBuffer.allocate (count); + read (buffer, position); + buffer.flip(); + } + + return target.write (buffer); + } + + public long transferTo (long position, long count, + WritableByteChannel target) throws IOException { if (position < 0 @@ -295,14 +318,57 @@ public final class FileChannelImpl extends FileChannel if ((mode & READ) == 0) throw new NonReadableChannelException (); - // XXX: count needs to be casted from long to int. Dataloss ? - ByteBuffer buffer = ByteBuffer.allocate ((int) count); - read (buffer, position); - buffer.flip(); - return target.write (buffer); + final int pageSize = 65536; + long total = 0; + + while (count > 0) + { + int transferred + = smallTransferTo (position, (int)Math.min (count, pageSize), + target); + if (transferred < 0) + break; + total += transferred; + position += transferred; + count -= transferred; + } + + return total; } - public long transferFrom (ReadableByteChannel src, long position, long count) + // like transferFrom, but with a count of less than 2Gbytes + private int smallTransferFrom (ReadableByteChannel src, long position, + int count) + throws IOException + { + ByteBuffer buffer = null; + + if (src instanceof FileChannel) + { + try + { + // Try to use a mapped buffer if we can. If this fails + // for any reason we'll fall back to using a ByteBuffer. + buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position, + count); + } + catch (IOException e) + { + } + } + + if (buffer == null) + { + buffer = ByteBuffer.allocate ((int) count); + src.read (buffer); + buffer.flip(); + } + + return write (buffer, position); + } + + public long transferFrom (ReadableByteChannel src, long position, + long count) throws IOException { if (position < 0 @@ -315,11 +381,21 @@ public final class FileChannelImpl extends FileChannel if ((mode & WRITE) == 0) throw new NonWritableChannelException (); - // XXX: count needs to be casted from long to int. Dataloss ? - ByteBuffer buffer = ByteBuffer.allocate ((int) count); - src.read (buffer); - buffer.flip(); - return write (buffer, position); + final int pageSize = 65536; + long total = 0; + + while (count > 0) + { + int transferred = smallTransferFrom (src, position, + (int)Math.min (count, pageSize)); + if (transferred < 0) + break; + total += transferred; + position += transferred; + count -= transferred; + } + + return total; } public FileLock tryLock (long position, long size, boolean shared)