Skip to content

Instantly share code, notes, and snippets.

@angerman
Created December 4, 2009 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save angerman/249027 to your computer and use it in GitHub Desktop.
Save angerman/249027 to your computer and use it in GitHub Desktop.
/** A subclass of RandomAccessFile to enable basic buffering to a byte array
* Copyright (C) 2009 minddumped.blogspot.com
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program 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 for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
import java.io.RandomAccessFile;
import java.io.FileNotFoundException;
import java.io.File;
import java.io.IOException;
import clojure.lang.IObj;
import clojure.lang.IPersistentMap;
/**
*
* @author minddumped.blogspot.com
*/
public class BufferedRandomAccessFile
extends RandomAccessFile
implements IObj {
private final static int _bufferlength = 65536;
public BufferedRandomAccessFile(IPersistentMap meta,
File file,
String mode,
int bufflen)
throws FileNotFoundException {
super(file, mode); _meta = meta; init(file, mode, bufflen);
}
public BufferedRandomAccessFile(File file, String mode, int bufflen)
throws FileNotFoundException {
super(file, mode); _meta = null; init(file, mode, bufflen);
}
public BufferedRandomAccessFile(IPersistentMap meta, File file, String mode)
throws FileNotFoundException {
super(file, mode); _meta = meta; init(file, mode, _bufferlength);
}
public BufferedRandomAccessFile(File file, String mode)
throws FileNotFoundException {
super(file, mode); _meta = null; init(file, mode, _bufferlength);
}
public BufferedRandomAccessFile(IPersistentMap meta, File file)
throws FileNotFoundException {
super(file, "r"); _meta = meta; init(file,"r", _bufferlength);
}
public BufferedRandomAccessFile(File file)
throws FileNotFoundException {
super(file, "r"); _meta = null; init(file, "r", _bufferlength);
}
public BufferedRandomAccessFile(IPersistentMap meta,
File file,
String mode,
int bufflen,
long position)
throws FileNotFoundException, IOException {
super(file, mode); _meta = meta; init(file, mode, bufflen);
seek(position);
}
public BufferedRandomAccessFile(File file, String mode, int bufflen, long position)
throws FileNotFoundException, IOException {
super(file, mode); _meta = null; init(file, mode, bufflen);
seek(position);
}
public BufferedRandomAccessFile(IPersistentMap meta,
File file,
String mode,
long position)
throws FileNotFoundException, IOException {
super(file, mode); _meta = meta; init(file, mode, _bufferlength);
seek(position);
}
public BufferedRandomAccessFile(File file, String mode, long position)
throws FileNotFoundException, IOException {
super(file, mode); _meta = null; init(file, mode, _bufferlength);
seek(position);
}
private void init(File file, String mode, int bufflen) {
bufferlength = bufflen;
bytebuffer = new byte[bufferlength];
maxread = 0;
buffpos = 0;
sb = new StringBuilder("0");
_file = file;
_mode = mode;
}
private byte[] bytebuffer;
private int bufferlength;
private int maxread;
private int buffpos;
private StringBuilder sb;
// Clojure Meta support
final IPersistentMap _meta;
private File _file;
private String _mode;
final public IPersistentMap meta(){
return _meta;
}
public BufferedRandomAccessFile withMeta(IPersistentMap meta) {
if(meta != _meta)
try {
return new BufferedRandomAccessFile(meta, _file, _mode, bufferlength, getFilePointer());
} catch (Exception e) { return null; } // FIXME
return this;
}
public int getbuffpos() {
return buffpos;
}
@Override
public int read() throws IOException {
if (buffpos >= maxread) {
maxread = readchunk();
if (maxread == -1) {
return -1;
}
}
buffpos++;
return bytebuffer[buffpos - 1];
}
public String readLine2() throws IOException {
sb.delete(0, sb.length());
int c = -1;
boolean eol = false;
while (!eol) {
switch (c = read()) {
case -1:
case '\n':
eol = true;
break;
case '\r':
eol = true;
long cur = getFilePointer();
if ((read()) != '\n') {
seek(cur);
}
break;
default:
sb.append((char) c);
break;
}
}
if ((c == -1) && (sb.length() == 0)) {
return null;
}
return sb.toString();
}
@Override
public long getFilePointer() throws IOException {
return super.getFilePointer() + buffpos;
}
@Override
public void seek(long pos) throws IOException {
if (maxread != -1 && pos < (super.getFilePointer() + maxread) && pos > super.getFilePointer()) {
Long diff = (pos - super.getFilePointer());
if (diff < Integer.MAX_VALUE) {
buffpos = diff.intValue();
} else {
throw new IOException("something wrong w/ seek");
}
} else {
buffpos = 0;
super.seek(pos);
maxread = readchunk();
}
}
private int readchunk() throws IOException {
long pos = super.getFilePointer() + buffpos;
super.seek(pos);
int read = super.read(bytebuffer);
super.seek(pos);
buffpos = 0;
return read;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment