@Override public FileChannel position(long pos) throws IOException { checkFileSizeLimit(pos); this.pos = (int) pos; return this; }
FileNioMapped(String fileName, String mode) throws IOException { if ("r".equals(mode)) { this.mode = MapMode.READ_ONLY; } else { this.mode = MapMode.READ_WRITE; } this.name = fileName; file = new RandomAccessFile(fileName, mode); reMap(); }
@Override public synchronized FileChannel truncate(long newLength) throws IOException { // compatibility with JDK FileChannel#truncate if (mode == MapMode.READ_ONLY) { throw new NonWritableChannelException(); } if (newLength < size()) { setFileLength(newLength); } return this; }
public synchronized void setFileLength(long newLength) throws IOException { checkFileSizeLimit(newLength); int oldPos = pos; unMap(); for (int i = 0;; i++) { try { file.setLength(newLength); break; } catch (IOException e) { if (i > 16 || e.toString().indexOf("user-mapped section open") < 0) { throw e; } } System.gc(); } reMap(); pos = (int) Math.min(newLength, oldPos); }
/** * Re-map byte buffer into memory, called when file size has changed or file * was created. */ private void reMap() throws IOException { int oldPos = 0; if (mapped != null) { oldPos = pos; unMap(); } fileLength = file.length(); checkFileSizeLimit(fileLength); // maps new MappedByteBuffer; the old one is disposed during GC mapped = file.getChannel().map(mode, 0, fileLength); int limit = mapped.limit(); int capacity = mapped.capacity(); if (limit < fileLength || capacity < fileLength) { throw new IOException("Unable to map: length=" + limit + " capacity=" + capacity + " length=" + fileLength); } if (SysProperties.NIO_LOAD_MAPPED) { mapped.load(); } this.pos = Math.min(oldPos, (int) fileLength); }
@Override public void implCloseChannel() throws IOException { if (file != null) { unMap(); file.close(); file = null; } }
@Override public FileChannel open(String mode) throws IOException { return new FileNioMapped(name.substring(getScheme().length() + 1), mode); }
@Override public synchronized int write(ByteBuffer src) throws IOException { int len = src.remaining(); // check if need to expand file if (mapped.capacity() < pos + len) { setFileLength(pos + len); } mapped.position(pos); mapped.put(src); pos += len; return len; }