@Test public void testRead() throws IOException { RegularFile file = regularFile(20); FileChannel channel = channel(file, READ); assertEquals(0, channel.position()); ByteBuffer buf = buffer("1234567890"); ByteBuffer buf2 = buffer("123457890"); assertEquals(10, channel.read(buf)); assertEquals(10, channel.position()); buf.flip(); assertEquals(10, channel.read(new ByteBuffer[] {buf, buf2})); assertEquals(20, channel.position()); buf.flip(); buf2.flip(); file.write(20, new byte[10], 0, 10); assertEquals(10, channel.read(new ByteBuffer[] {buf, buf2}, 0, 2)); assertEquals(30, channel.position()); buf.flip(); assertEquals(10, channel.read(buf, 5)); assertEquals(30, channel.position()); buf.flip(); assertEquals(-1, channel.read(buf)); assertEquals(30, channel.position()); }
@Test public void testAsynchronousClose() throws IOException, InterruptedException { RegularFile file = regularFile(10); final FileChannel channel = channel(file, READ, WRITE); file.writeLock().lock(); // ensure all operations on the channel will block ExecutorService executor = Executors.newCachedThreadPool(); List<Future<?>> futures = queueAllBlockingOperations(channel, executor); // ensure time for operations to start blocking Uninterruptibles.sleepUninterruptibly(10, MILLISECONDS); channel.close(); for (Future<?> future : futures) { try { future.get(); fail(); } catch (ExecutionException expected) { assertTrue(expected.getCause() instanceof AsynchronousCloseException); } } }
@Test public void testCloseByInterrupt() throws IOException, InterruptedException { RegularFile file = regularFile(10); final FileChannel channel = channel(file, READ, WRITE); file.writeLock().lock(); // ensure all operations on the channel will block ExecutorService executor = Executors.newCachedThreadPool(); final CountDownLatch latch = new CountDownLatch(1); final AtomicReference<Throwable> interruptException = new AtomicReference<>(); // This thread, being the first to run, will be blocking on the interruptible lock (the byte // file's write lock) and as such will be interrupted properly... the other threads will be // blocked on the lock that guards the position field and the specification that only one method // on the channel will be in progress at a time. That lock is not interruptible, so we must // interrupt this thread. Thread thread = new Thread( new Runnable() { @Override public void run() { try { channel.write(ByteBuffer.allocate(20)); latch.countDown(); } catch (Throwable e) { interruptException.set(e); latch.countDown(); } } }); thread.start(); // ensure time for thread to start blocking on the write lock Uninterruptibles.sleepUninterruptibly(5, MILLISECONDS); List<Future<?>> futures = queueAllBlockingOperations(channel, executor); // ensure time for operations to start blocking Uninterruptibles.sleepUninterruptibly(10, MILLISECONDS); // interrupting this blocking thread closes the channel and makes all the other threads // throw AsynchronousCloseException... the operation on this thread should throw // ClosedByInterruptException thread.interrupt(); latch.await(); assertTrue(interruptException.get() instanceof ClosedByInterruptException); for (Future<?> future : futures) { try { future.get(); fail(); } catch (ExecutionException expected) { assertTrue(expected.getCause() instanceof AsynchronousCloseException); } } }
@Test public void testSize() throws IOException { RegularFile file = regularFile(10); FileChannel channel = channel(file, READ); assertEquals(10, channel.size()); file.write(10, new byte[90], 0, 90); assertEquals(100, channel.size()); }
@Test public void testTruncate() throws IOException { RegularFile file = regularFile(10); FileChannel channel = channel(file, WRITE); channel.truncate(10); // no resize, >= size assertEquals(10, file.size()); channel.truncate(11); // no resize, > size assertEquals(10, file.size()); channel.truncate(5); // resize down to 5 assertEquals(5, file.size()); channel.position(20); channel.truncate(10); assertEquals(10, channel.position()); channel.truncate(2); assertEquals(2, channel.position()); }
@Test public void testFileTimeUpdates() throws IOException { RegularFile file = regularFile(10); FileChannel channel = new JimfsFileChannel( file, ImmutableSet.<OpenOption>of(READ, WRITE), new FileSystemState(Runnables.doNothing())); // accessed long accessTime = file.getLastAccessTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.read(ByteBuffer.allocate(10)); assertNotEquals(accessTime, file.getLastAccessTime()); accessTime = file.getLastAccessTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.read(ByteBuffer.allocate(10), 0); assertNotEquals(accessTime, file.getLastAccessTime()); accessTime = file.getLastAccessTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.read(new ByteBuffer[] {ByteBuffer.allocate(10)}); assertNotEquals(accessTime, file.getLastAccessTime()); accessTime = file.getLastAccessTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.read(new ByteBuffer[] {ByteBuffer.allocate(10)}, 0, 1); assertNotEquals(accessTime, file.getLastAccessTime()); accessTime = file.getLastAccessTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.transferTo(0, 10, new ByteBufferChannel(10)); assertNotEquals(accessTime, file.getLastAccessTime()); // modified long modifiedTime = file.getLastModifiedTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.write(ByteBuffer.allocate(10)); assertNotEquals(modifiedTime, file.getLastModifiedTime()); modifiedTime = file.getLastModifiedTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.write(ByteBuffer.allocate(10), 0); assertNotEquals(modifiedTime, file.getLastModifiedTime()); modifiedTime = file.getLastModifiedTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.write(new ByteBuffer[] {ByteBuffer.allocate(10)}); assertNotEquals(modifiedTime, file.getLastModifiedTime()); modifiedTime = file.getLastModifiedTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.write(new ByteBuffer[] {ByteBuffer.allocate(10)}, 0, 1); assertNotEquals(modifiedTime, file.getLastModifiedTime()); modifiedTime = file.getLastModifiedTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.truncate(0); assertNotEquals(modifiedTime, file.getLastModifiedTime()); modifiedTime = file.getLastModifiedTime(); Uninterruptibles.sleepUninterruptibly(2, MILLISECONDS); channel.transferFrom(new ByteBufferChannel(10), 0, 10); assertNotEquals(modifiedTime, file.getLastModifiedTime()); }