package org.jcodec.common; import static java.lang.System.currentTimeMillis; import org.jcodec.common.io.AutoPool; import org.jcodec.common.io.AutoResource; import org.jcodec.common.io.SeekableByteChannel; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * @author The JCodec project * */ public class AutoFileChannelWrapper implements SeekableByteChannel, AutoResource { private static final long THRESHOLD = 5000; // five seconds private FileChannel ch; private File file; private long savedPos; private long curTime; private long accessTime; public AutoFileChannelWrapper(File file) throws IOException { this.file = file; this.curTime = currentTimeMillis(); AutoPool.getInstance().add(this); ensureOpen(); } private void ensureOpen() throws IOException { accessTime = curTime; if (ch == null || !ch.isOpen()) { ch = new FileInputStream(file).getChannel(); ch.position(savedPos); } } @Override public int read(ByteBuffer arg0) throws IOException { ensureOpen(); int r = ch.read(arg0); savedPos = ch.position(); return r; } @Override public void close() throws IOException { if (ch != null && ch.isOpen()) { savedPos = ch.position(); ch.close(); ch = null; } } @Override public boolean isOpen() { return ch != null && ch.isOpen(); } @Override public int write(ByteBuffer arg0) throws IOException { ensureOpen(); int w = ch.write(arg0); savedPos = ch.position(); return w; } @Override public long position() throws IOException { ensureOpen(); return ch.position(); } @Override public SeekableByteChannel setPosition(long newPosition) throws IOException { ensureOpen(); ch.position(newPosition); savedPos = newPosition; return this; } @Override public long size() throws IOException { ensureOpen(); return ch.size(); } @Override public SeekableByteChannel truncate(long size) throws IOException { ensureOpen(); ch.truncate(size); savedPos = ch.position(); return this; } @Override public void setCurTime(long curTime) { this.curTime = curTime; if (ch != null && ch.isOpen() && curTime - accessTime > THRESHOLD) { try { close(); } catch (IOException e) { throw new RuntimeException(e); } } } }