jdk/test/java/nio/channels/FileChannel/TransferTo6GBFile.java
changeset 44273 a2e3e08c5468
child 44363 bdc8543c97f5
equal deleted inserted replaced
44272:4d16899cb312 44273:a2e3e08c5468
       
     1 /*
       
     2  * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /* @test
       
    25  * @bug 6253145
       
    26  * @key intermittent
       
    27  * @summary Test FileChannel.transferTo with file positions up to 8GB
       
    28  * @run testng/timeout=300 TransferTo6GBFile
       
    29  */
       
    30 
       
    31 import java.io.File;
       
    32 import java.io.IOException;
       
    33 import java.io.PrintStream;
       
    34 import java.io.RandomAccessFile;
       
    35 import java.net.InetAddress;
       
    36 import java.net.InetSocketAddress;
       
    37 import java.nio.ByteBuffer;
       
    38 import java.nio.channels.FileChannel;
       
    39 import java.nio.channels.ServerSocketChannel;
       
    40 import java.nio.channels.SocketChannel;
       
    41 import java.util.concurrent.TimeUnit;
       
    42 
       
    43 import org.testng.annotations.Test;
       
    44 
       
    45 public class TransferTo6GBFile {
       
    46 
       
    47     private static PrintStream err = System.err;
       
    48     private static PrintStream out = System.out;
       
    49 
       
    50     // Test transferTo with file positions larger than 2 and 4GB
       
    51     @Test
       
    52     public void xferTest08() throws Exception { // for bug 6253145
       
    53         // Creating a sparse 6GB file on Windows takes too long
       
    54         String osName = System.getProperty("os.name");
       
    55         if (osName.startsWith("Windows"))
       
    56             return;
       
    57 
       
    58         final long G = 1024L * 1024L * 1024L;
       
    59 
       
    60         // Create 6GB file
       
    61 
       
    62         File file = File.createTempFile("source", null);
       
    63         file.deleteOnExit();
       
    64 
       
    65         RandomAccessFile raf = new RandomAccessFile(file, "rw");
       
    66         FileChannel fc = raf.getChannel();
       
    67 
       
    68         out.println("  Writing large file...");
       
    69         long t0 = System.nanoTime();
       
    70         try {
       
    71             fc.write(ByteBuffer.wrap("0123456789012345".getBytes("UTF-8")), 6*G);
       
    72             long t1 = System.nanoTime();
       
    73             out.printf("  Wrote large file in %d ns (%d ms) %n",
       
    74             t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
       
    75         } catch (IOException x) {
       
    76             err.println("  Unable to create test file:" + x);
       
    77             fc.close();
       
    78             return;
       
    79         }
       
    80 
       
    81         // Setup looback connection and echo server
       
    82 
       
    83         ServerSocketChannel ssc = ServerSocketChannel.open();
       
    84         ssc.socket().bind(new InetSocketAddress(0));
       
    85 
       
    86         InetAddress lh = InetAddress.getLocalHost();
       
    87         InetSocketAddress isa = new InetSocketAddress(lh, ssc.socket().getLocalPort());
       
    88         SocketChannel source = SocketChannel.open(isa);
       
    89         SocketChannel sink = ssc.accept();
       
    90 
       
    91         Thread thr = new Thread(new EchoServer(sink));
       
    92         thr.start();
       
    93 
       
    94         // Test data is array of positions and counts
       
    95 
       
    96         long testdata[][] = {
       
    97             { 2*G-1,    1 },
       
    98             { 2*G-1,    10 },       // across 2GB boundary
       
    99             { 2*G,      1 },
       
   100             { 2*G,      10 },
       
   101             { 2*G+1,    1 },
       
   102             { 4*G-1,    1 },
       
   103             { 4*G-1,    10 },       // across 4GB boundary
       
   104             { 4*G,      1 },
       
   105             { 4*G,      10 },
       
   106             { 4*G+1,    1 },
       
   107             { 5*G-1,    1 },
       
   108             { 5*G-1,    10 },
       
   109             { 5*G,      1 },
       
   110             { 5*G,      10 },
       
   111             { 5*G+1,    1 },
       
   112             { 6*G,      1 },
       
   113         };
       
   114 
       
   115         ByteBuffer sendbuf = ByteBuffer.allocateDirect(100);
       
   116         ByteBuffer readbuf = ByteBuffer.allocateDirect(100);
       
   117 
       
   118         try {
       
   119             byte value = 0;
       
   120             for (int i=0; i<testdata.length; i++) {
       
   121                 long position = testdata[(int)i][0];
       
   122                 long count = testdata[(int)i][1];
       
   123 
       
   124                 // generate bytes
       
   125                 for (long j=0; j<count; j++) {
       
   126                     sendbuf.put(++value);
       
   127                 }
       
   128                 sendbuf.flip();
       
   129 
       
   130                 // write to file and transfer to echo server
       
   131                 fc.write(sendbuf, position);
       
   132                 t0 = System.nanoTime();
       
   133                 fc.transferTo(position, count, source);
       
   134                 out.printf("  transferTo(%d, %2d, source): %d ns%n",
       
   135                     position, count, System.nanoTime() - t0);
       
   136 
       
   137                 // read from echo server
       
   138                 long nread = 0;
       
   139                 while (nread < count) {
       
   140                     int n = source.read(readbuf);
       
   141                     if (n < 0)
       
   142                         throw new RuntimeException("Premature EOF!");
       
   143                     nread += n;
       
   144                 }
       
   145 
       
   146                 // check reply from echo server
       
   147                 readbuf.flip();
       
   148                 sendbuf.flip();
       
   149                 if (!readbuf.equals(sendbuf))
       
   150                     throw new RuntimeException("Echoed bytes do not match!");
       
   151                 readbuf.clear();
       
   152                 sendbuf.clear();
       
   153             }
       
   154         } finally {
       
   155             source.close();
       
   156             ssc.close();
       
   157             fc.close();
       
   158             file.delete();
       
   159         }
       
   160     }
       
   161 
       
   162     /**
       
   163      * Simple in-process server to echo bytes read by a given socket channel
       
   164      */
       
   165     static class EchoServer implements Runnable {
       
   166         private SocketChannel sc;
       
   167 
       
   168         public EchoServer(SocketChannel sc) {
       
   169             this.sc = sc;
       
   170         }
       
   171 
       
   172         public void run() {
       
   173             ByteBuffer bb = ByteBuffer.allocateDirect(1024);
       
   174             try {
       
   175                 for (;;) {
       
   176                     int n = sc.read(bb);
       
   177                     if (n < 0)
       
   178                         break;
       
   179 
       
   180                     bb.flip();
       
   181                     while (bb.remaining() > 0) {
       
   182                         sc.write(bb);
       
   183                     }
       
   184                     bb.clear();
       
   185                 }
       
   186             } catch (IOException x) {
       
   187                 x.printStackTrace();
       
   188             } finally {
       
   189                 try {
       
   190                     sc.close();
       
   191                 } catch (IOException ignore) { }
       
   192             }
       
   193         }
       
   194     }
       
   195 }