Path: blob/master/test/jdk/java/nio/channels/FileChannel/directio/ReadDirect.java
41161 views
/*1* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 816490025* @summary Test read method of FileChannel with DirectIO26* (use -Dseed=X to set PRNG seed)27* @library .. /test/lib28* @build jdk.test.lib.RandomFactory29* DirectIOTest30* @run main/othervm ReadDirect31* @key randomness32*/3334import java.io.*;35import java.nio.ByteBuffer;36import java.nio.CharBuffer;37import java.nio.channels.*;38import java.nio.file.Files;39import java.nio.file.FileStore;40import java.nio.file.Path;41import java.nio.file.Paths;42import java.nio.file.StandardOpenOption;43import java.util.Random;44import com.sun.nio.file.ExtendedOpenOption;4546import jdk.test.lib.RandomFactory;4748public class ReadDirect {4950private static PrintStream err = System.err;5152private static Random generator = RandomFactory.getRandom();5354private static int charsPerGroup = -1;5556private static int alignment = -1;5758private static boolean initTests() throws Exception {59Path p = DirectIOTest.createTempFile();60try {61FileStore fs = Files.getFileStore(p);62alignment = (int)fs.getBlockSize();63charsPerGroup = alignment;64} finally {65Files.delete(p);66}67return true;68}6970private static void testWithSingleBuffer() throws Exception {71StringBuffer sb = new StringBuffer();72sb.setLength(2);7374Path p = DirectIOTest.createTempFile();7576initTestFile(p);77try (FileChannel fc = FileChannel.open(p,78StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,79ExtendedOpenOption.DIRECT)) {80ByteBuffer block = ByteBuffer.allocateDirect(charsPerGroup81+ alignment - 1).alignedSlice(alignment);82for (int x = 0; x < 100; x++) {83block.clear();84long offset = x * charsPerGroup;85long expectedResult = offset / charsPerGroup;86fc.read(block);8788for (int i = 0; i < 2; i++) {89byte aByte = block.get(i);90sb.setCharAt(i, (char)aByte);91}92int result = Integer.parseInt(sb.toString());93if (result != expectedResult) {94err.println("I expected " + expectedResult);95err.println("I got " + result);96throw new Exception("Read test failed");97}98}99}100}101102private static void testWithNotAlignedBufferSize() throws Exception {103int bufferSize = charsPerGroup - 1;104Path p = DirectIOTest.createTempFile();105106try (OutputStream fos = Files.newOutputStream(p)) {107fos.write(new byte[bufferSize]);108}109110try (FileChannel fc = FileChannel.open(p,111StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,112ExtendedOpenOption.DIRECT)) {113ByteBuffer block = ByteBuffer.allocate(bufferSize);114try {115fc.read(block);116throw new RuntimeException("Expected exception not thrown");117} catch (IOException e) {118if (!e.getMessage().contains("Number of remaining bytes ("119+ bufferSize + ") is not a multiple of the block size ("120+ alignment + ")"))121throw new Exception("Read test failed");122}123}124}125126private static void testWithNotAlignedBufferOffset() throws Exception {127int bufferSize = charsPerGroup * 2;128int pos = alignment - 1;129130Path p = DirectIOTest.createTempFile();131132try (OutputStream fos = Files.newOutputStream(p)) {133fos.write(new byte[bufferSize]);134}135136try (FileChannel fc = FileChannel.open(p,137StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,138ExtendedOpenOption.DIRECT)) {139ByteBuffer block = ByteBuffer.allocateDirect(bufferSize);140block.position(pos);141block.limit(bufferSize - 1);142try {143fc.read(block);144throw new RuntimeException("Expected exception not thrown");145} catch (IOException e) {146if (!e.getMessage().contains("Current location of the bytebuffer "147+ "(" + pos + ") is not a multiple of the block size ("148+ alignment + ")"))149throw new Exception("Read test failed");150}151}152}153154private static void testWithArrayOfBuffer() throws Exception {155StringBuffer sb = new StringBuffer();156sb.setLength(2);157ByteBuffer[] dests = new ByteBuffer[4];158Path p = DirectIOTest.createTempFile();159160initTestFile(p);161162try (FileChannel fc = FileChannel.open(p,163StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,164ExtendedOpenOption.DIRECT)) {165int randomNumber = -1;166167for (int i = 0; i < 4; i++) {168dests[i] = ByteBuffer.allocateDirect169(charsPerGroup + alignment - 1).alignedSlice(alignment);170for (int j = 0; j < charsPerGroup; j++) {171dests[i].put(j, (byte)'a');172}173}174175// The size of the test FileChannel is 100*charsPerGroup.176// As the channel bytes will be scattered into two buffers177// each of size charsPerGroup, the offset cannot be greater178// than 98*charsPerGroup, so the value of randomNumber must179// be in the range [0,98], i.e., 0 <= randomNumber < 99.180randomNumber = generator.nextInt(99);181long offset = randomNumber * charsPerGroup;182fc.position(offset);183fc.read(dests, 1, 2);184185for (int i = 0; i < 4; i++) {186if (i == 1 || i == 2) {187for (int j = 0; j < 2; j++) {188byte aByte = dests[i].get(j);189sb.setCharAt(j, (char)aByte);190}191int result = Integer.parseInt(sb.toString());192int expectedResult = randomNumber + i - 1;193if (result != expectedResult) {194err.println("I expected " + expectedResult);195err.println("I got " + result);196throw new Exception("Read test failed");197}198} else {199for (int k = 0; k < charsPerGroup; k++) {200if (dests[i].get(k) != (byte)'a')201throw new RuntimeException("Read test failed");202}203}204}205}206}207208public static void testOnEOF() throws Exception {209int bufferSize = charsPerGroup / 2;210Path p = DirectIOTest.createTempFile();211212try (OutputStream fos = Files.newOutputStream(p)) {213byte[] writeBlock = new byte[bufferSize];214for (int i = 0; i < bufferSize; i++) {215writeBlock[i] = ((byte)'a');216}217fos.write(writeBlock);218}219220try (FileChannel fc = FileChannel.open(p,221StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE,222ExtendedOpenOption.DIRECT)) {223ByteBuffer block = ByteBuffer.allocateDirect(224(bufferSize / alignment + 1) * alignment + alignment - 1)225.alignedSlice(alignment);226int result = fc.read(block);227if (result != bufferSize) {228err.println("Number of bytes to read " + bufferSize);229err.println("I read " + result);230throw new Exception("Read test failed");231}232for (int j = 0; j < bufferSize; j++) {233if (block.get(j) != (byte)'a')234throw new RuntimeException("Read test failed");235}236}237}238239public static void main(String[] args) throws Exception {240if (initTests()) {241testWithSingleBuffer();242testWithNotAlignedBufferSize();243testWithNotAlignedBufferOffset();244testWithArrayOfBuffer();245testOnEOF();246}247}248249private static void initTestFile(Path p)250throws Exception {251try (OutputStream fos = Files.newOutputStream(p)) {252try (BufferedWriter awriter253= new BufferedWriter(new OutputStreamWriter(fos, "8859_1"))) {254for (int i = 0; i < 100; i++) {255String number = new Integer(i).toString();256for (int h = 0; h < 2 - number.length(); h++)257awriter.write("0");258awriter.write("" + i);259for (int j = 0; j < (charsPerGroup - 2); j++)260awriter.write("0");261}262awriter.flush();263}264}265}266}267268269