1 /* 2 * Copyright (c) 2001, 2010, 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 4452020 4629048 4638365 4869859 26 * @summary Test FileChannel scattering reads 27 * @run main/othervm ScatteringRead 28 */ 29 30 import java.nio.channels.*; 31 import java.nio.*; 32 import java.io.*; 33 34 public class ScatteringRead { 35 36 private static final int NUM_BUFFERS = 3; 37 38 private static final int BUFFER_CAP = 3; 39 40 private static final int BIG_BUFFER_CAP = Integer.MAX_VALUE / 3 + 10; 41 42 public static void main(String[] args) throws Exception { 43 test1(); // for bug 4452020 44 test2(); // for bug 4629048 45 System.gc(); 46 47 // Test 3 proves that the system is capable of reading 48 // more than MAX_INT bytes in one shot. But it is unsuitable 49 // for automated testing because oftentimes less bytes are 50 // read for various reasons, and this is allowed by the spec. 51 // test3(); // for bug 4638365 52 } 53 54 private static void test1() throws Exception { 55 ByteBuffer dstBuffers[] = new ByteBuffer[NUM_BUFFERS]; 56 for (int i=0; i<NUM_BUFFERS; i++) 57 dstBuffers[i] = ByteBuffer.allocateDirect(BUFFER_CAP); 58 File blah = File.createTempFile("blah1", null); 59 blah.deleteOnExit(); 60 createTestFile(blah); 61 62 FileInputStream fis = new FileInputStream(blah); 63 FileChannel fc = fis.getChannel(); 64 65 byte expectedResult = -128; 66 for (int k=0; k<20; k++) { 67 long bytesRead = fc.read(dstBuffers); 68 for (int i=0; i<NUM_BUFFERS; i++) { 69 for (int j=0; j<BUFFER_CAP; j++) { 70 byte b = dstBuffers[i].get(j); 71 if (b != expectedResult++) 72 throw new RuntimeException("Test failed"); 73 } 74 dstBuffers[i].flip(); 75 } 76 } 77 fis.close(); 78 } 79 80 private static void createTestFile(File blah) throws Exception { 81 FileOutputStream fos = new FileOutputStream(blah); 82 for(int i=-128; i<128; i++) 83 fos.write((byte)i); 84 fos.flush(); 85 fos.close(); 86 } 87 88 private static void test2() throws Exception { 89 ByteBuffer dstBuffers[] = new ByteBuffer[2]; 90 for (int i=0; i<2; i++) 91 dstBuffers[i] = ByteBuffer.allocateDirect(10); 92 File blah = File.createTempFile("blah2", null); 93 blah.deleteOnExit(); 94 FileOutputStream fos = new FileOutputStream(blah); 95 for(int i=0; i<15; i++) 96 fos.write((byte)92); 97 fos.flush(); 98 fos.close(); 99 100 FileInputStream fis = new FileInputStream(blah); 101 FileChannel fc = fis.getChannel(); 102 103 long bytesRead = fc.read(dstBuffers); 104 if (dstBuffers[1].limit() != 10) 105 throw new Exception("Scattering read changed buf limit."); 106 fis.close(); 107 } 108 109 private static void test3() throws Exception { 110 // Only works on 64 bit Solaris 111 String osName = System.getProperty("os.name"); 112 if (!osName.startsWith("SunOS")) 113 return; 114 String dataModel = System.getProperty("sun.arch.data.model"); 115 if (!dataModel.startsWith("64")) 116 return; 117 118 ByteBuffer dstBuffers[] = new ByteBuffer[NUM_BUFFERS]; 119 File f = File.createTempFile("test3", null); 120 f.deleteOnExit(); 121 prepTest3File(f, (long)BIG_BUFFER_CAP); 122 RandomAccessFile raf = new RandomAccessFile(f, "rw"); 123 FileChannel fc = raf.getChannel(); 124 MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 125 BIG_BUFFER_CAP); 126 for (int i=0; i<NUM_BUFFERS; i++) { 127 dstBuffers[i] = mbb; 128 } 129 fc.close(); 130 raf.close(); 131 132 // Source must be large 133 FileInputStream fis = new FileInputStream("/dev/zero"); 134 fc = fis.getChannel(); 135 136 long bytesRead = fc.read(dstBuffers); 137 if (bytesRead <= Integer.MAX_VALUE) 138 throw new RuntimeException("Test 3 failed "+bytesRead+" < "+Integer.MAX_VALUE); 139 140 fc.close(); 141 fis.close(); 142 } 143 144 static void prepTest3File(File blah, long testSize) throws Exception { 145 RandomAccessFile raf = new RandomAccessFile(blah, "rw"); 146 FileChannel fc = raf.getChannel(); 147 fc.write(ByteBuffer.wrap("Use the source!".getBytes()), testSize - 40); 148 fc.close(); 149 raf.close(); 150 } 151 152 }