
org.monte.media.binary.FileBasedBinaryModel Maven / Gradle / Ivy
/*
* @(#)FileBasedBinaryModel.java 1.0.1 2010-05-24
*
* Copyright (c) 2010 Werner Randelshofer, Goldau, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
package org.monte.media.binary;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.WeakHashMap;
/**
* FileBasedBinaryModel.
*
* FIXME - The file based binary model may grow infinitely large.
*
* @author Werner Randelshofer
* @version 1.0.1 2010-05-24 Method getBytes sometimes returned invalid length.
*
1.0 2010-04-09 Created.
*/
public class FileBasedBinaryModel implements BinaryModel {
private int segsize = 1024;
private long offset;
private long length;
private RandomAccessFile racf;
private WeakHashMap cache = new WeakHashMap();
private File file;
public FileBasedBinaryModel(File file) throws IOException {
this(file, 0, file.length());
}
public FileBasedBinaryModel(File file, long offset, long length) throws IOException {
racf = new RandomAccessFile(file, "r");
this.offset = offset;
this.length = length;
this.file = file;
}
@Override
public String toString() {
return "FileBasedBinaryModel " + file.getName() + " " + offset + " " + length;
}
@Override
public long getLength() {
return length;
}
@Override
public int getBytes(long off, int len, byte[] target) {
byte[] cdat = cache.get(off);
if (off + len > length) {
len = (int) (length - off);
}
if (cdat != null) {
if (cdat.length >= len) {
System.arraycopy(cdat, 0, target, 0, len);
return len;
}
}
try {
//byte[] cdat = new byte[segsize];
racf.seek(off + offset);
racf.readFully(target, 0, len);
byte[] cached = target.clone();
cache.put(off, cached);
} catch (IOException ex) {
Arrays.fill(target, 0, len, (byte) 0);
ex.printStackTrace();
}
return len;
}
@Override
public void close() {
if (racf != null) {
try {
racf.close();
racf = null;
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
@Override
public void finalize() {
close();
}
}