OSDN Git Service

2005-03-09 Andrew Haley <aph@redhat.com>
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Mar 2005 15:29:15 +0000 (15:29 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Mar 2005 15:29:15 +0000 (15:29 +0000)
        * 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

libjava/ChangeLog
libjava/gnu/java/nio/channels/FileChannelImpl.java

index e55087c..f62317f 100644 (file)
@@ -1,3 +1,12 @@
+2005-03-09  Andrew Haley  <aph@redhat.com>
+
+       * 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  <ddaney@avtrex.com>
 
        PR libgcj/20389
index 887d1dc..e5b02e9 100644 (file)
@@ -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)