classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] Patch for FileChannelImpl lossage


From: Andrew Haley
Subject: [cp-patches] Patch for FileChannelImpl lossage
Date: Wed, 9 Mar 2005 18:44:17 +0000

This fixes a bug in FileChannelImpl where transferTo and transferFrom
break if they're asked to transfer more than 2Gbytes.  They also use
heinous amounts of memory.

In addition to fixing this bug, this new implementation is very much
faster, at least for large files.

Andrew.


2005-03-09  Andrew Haley  <address@hidden>

        * gnu/java/nio/channels/FileChannelImpl.java (smallTransferFrom):
        New.
        (smallTransferTo): New.
        (transferFrom): Loop around smallTransferFrom, copying pageSize
        bytes each time.
        (transferTo): Likewise.

Index: FileChannelImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/nio/channels/FileChannelImpl.java,v
retrieving revision 1.6
diff -p -2 -c -r1.6 FileChannelImpl.java
*** FileChannelImpl.java        17 Jul 2004 13:46:02 -0000      1.6
--- FileChannelImpl.java        9 Mar 2005 18:37:08 -0000
*************** public final class FileChannelImpl exten
*** 282,286 ****
    }
  
!   public long transferTo (long position, long count, WritableByteChannel 
target)
      throws IOException
    {
--- 282,309 ----
    }
  
!   // 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
    {
*************** public final class FileChannelImpl exten
*** 295,306 ****
         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);
    }
  
!   public long transferFrom (ReadableByteChannel src, long position, long 
count)
      throws IOException
    {
--- 318,372 ----
         throw new NonReadableChannelException ();
     
!     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;
    }
  
!   // 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
    {
*************** public final class FileChannelImpl exten
*** 315,323 ****
         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);
    }
  
--- 381,399 ----
         throw new NonWritableChannelException ();
  
!     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;
    }
  




reply via email to

[Prev in Thread] Current Thread [Next in Thread]