/* * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* @test * @bug 8204310 * @summary Check how FileChannel behaves if the file size/offset change via * RAF.setLength() and other methods. * @run main TruncateRAF */ import java.io.File; import java.io.RandomAccessFile; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class TruncateRAF { static void checkState(RandomAccessFile raf, FileChannel fch, long expectedOffset, long expectedLength) throws IOException { long rafLength = raf.length(); long rafOffset = raf.getFilePointer(); long fchLength = fch.size(); long fchOffset = fch.position(); if (rafLength != expectedLength) throw new RuntimeException("rafLength (" + rafLength + ") != " + "expectedLength (" + expectedLength + ")"); if (rafOffset != expectedOffset) throw new RuntimeException("rafOffset (" + rafOffset + ") != " + "expectedOffset (" + expectedOffset + ")"); if (fchLength != expectedLength) throw new RuntimeException("fchLength (" + fchLength + ") != " + "expectedLength (" + expectedLength + ")"); if (fchOffset != expectedOffset) throw new RuntimeException("fchOffset (" + fchOffset + ") != " + "expectedOffset (" + expectedOffset + ")"); } public static void main(String[] args) throws Throwable { File file = new File("tmp"); try (RandomAccessFile raf = new RandomAccessFile(file, "rw"); FileChannel fch = raf.getChannel()) { // initially empty checkState(raf, fch, 0, 0); // seeking beyond EOF raf.seek(42); checkState(raf, fch, 42, 0); // seeking beyond EOF fch.position(84); checkState(raf, fch, 84, 0); // writing at offset beyond EOF raf.write(1); checkState(raf, fch, 85, 85); // truncating raf.setLength(63); checkState(raf, fch, 63, 63); // writing at EOF fch.write(ByteBuffer.wrap(new byte[1])); checkState(raf, fch, 64, 64); // seeking at the middle fch.position(32); checkState(raf, fch, 32, 64); // truncating beyond offset fch.truncate(42); checkState(raf, fch, 32, 42); // truncating before offset fch.truncate(16); checkState(raf, fch, 16, 16); // writing at position beyond EOF fch.write(ByteBuffer.wrap(new byte[1]), 127); checkState(raf, fch, 16, 128); // writing at position before EOF fch.write(ByteBuffer.wrap(new byte[1]), 42); checkState(raf, fch, 16, 128); // truncating raf.setLength(64); checkState(raf, fch, 16, 64); // changing offset raf.seek(21); checkState(raf, fch, 21, 64); // skipping should change offset raf.skipBytes(4); checkState(raf, fch, 25, 64); // reading should change offset raf.read(); checkState(raf, fch, 26, 64); // truncating to zero raf.setLength(0); checkState(raf, fch, 0, 0); // FileChannel cannot expand size fch.truncate(42); checkState(raf, fch, 0, 0); // expanding raf.setLength(42); checkState(raf, fch, 0, 42); // seeking beyond EOF raf.seek(512); checkState(raf, fch, 512, 42); // truncating to the same size fch.truncate(256); checkState(raf, fch, 256, 42); // truncating to the same size fch.truncate(42); checkState(raf, fch, 42, 42); // truncating to zero fch.truncate(0); checkState(raf, fch, 0, 0); } } }