org.apache.zookeeper.graph.RandomAccessFileReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zookeeper-contrib-loggraph Show documentation
Show all versions of zookeeper-contrib-loggraph Show documentation
LogGraph is an application for viewing and filtering zookeeper logs. It can handle transaction logs and message logs.
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zookeeper.graph;
import java.io.File;
import java.io.Reader;
import java.io.IOException;
import java.io.EOFException;
import java.io.RandomAccessFile;
import java.io.FileNotFoundException;
import java.io.DataInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RandomAccessFileReader extends Reader implements DataInput {
private static final Logger LOG = LoggerFactory.getLogger(RandomAccessFileReader.class);
private RandomAccessFile file;
private byte[] buffer;
private int buffersize;
private int bufferoffset;
private long fileoffset;
private long fp;
private static final int DEFAULT_BUFFER_SIZE = 512*1024; // 512k
private int point = 0;
public RandomAccessFileReader(File f) throws FileNotFoundException {
file = new RandomAccessFile(f, "r");
if (LOG.isDebugEnabled()) {
try {
LOG.debug("Opened file(" + f + ") with FD (" + file.getFD() + ")");
} catch (IOException ioe) {
LOG.debug("Opened file(" + f + ") coulds get FD");
}
}
buffer = new byte[DEFAULT_BUFFER_SIZE];
buffersize = 0;
bufferoffset = 0;
fileoffset = 0;
fp = 0;
}
/**
fill the buffer from the file.
fp keeps track of the file pointer.
fileoffset is the offset into the file to where the buffer came from.
*/
private int fill() throws IOException {
fileoffset = fp;
int read = file.read(buffer, 0, buffer.length);
if (LOG.isDebugEnabled()) {
String buf = new String(buffer, 0, 40, "UTF-8");
LOG.debug("fill(buffer=" + buf + ")");
}
if (read == -1) { // eof reached
buffersize = 0;
} else {
buffersize = read;
}
fp += buffersize;
bufferoffset = 0;
return buffersize;
}
/**
* Reader interface
*/
public boolean markSupported() { return false; }
/**
copy what we can from buffer. if it's not enough, fill buffer again and copy again
*/
synchronized public int read(char[] cbuf, int off, int len) throws IOException {
// This could be faster, but probably wont be used
byte[] b = new byte[2];
int bytesread = 0;
while (len > 0) {
int read = read(b, 0, 2);
bytesread += read;
if (read < 2) {
return bytesread;
}
cbuf[off] = (char)((b[0] << 8) | (b[1] & 0xff));
off += read;
len -= read;
}
return bytesread;
}
synchronized public int read(byte[] buf, int off, int len) throws IOException {
if (LOG.isTraceEnabled()) {
LOG.trace("read(buf, off=" + off + ", len=" + len);
}
int read = 0;
while (len > 0) {
if (buffersize == 0) {
fill();
if (buffersize == 0) {
break;
}
}
int tocopy = Math.min(len, buffersize);
if (LOG.isTraceEnabled()) {
LOG.trace("tocopy=" + tocopy);
}
System.arraycopy(buffer, bufferoffset, buf, off, tocopy);
buffersize -= tocopy;
bufferoffset += tocopy;
len -= tocopy;
read += tocopy;
off += tocopy;
}
if (LOG.isTraceEnabled()) {
LOG.trace("read=" + read);
}
return read;
}
public void close() throws IOException {
file.close();
}
/**
* Seek interface
*/
public long getPosition() {
return bufferoffset + fileoffset;
}
synchronized public void seek(long pos) throws IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("seek(" + pos + ")");
}
file.seek(pos);
fp = pos;
buffersize = 0; // force a buffer fill on next read
}
/**
works like the usual readLine but disregards \r to make things easier
*/
synchronized public String readLine() throws IOException {
StringBuffer s = null;
// go through buffer until i find a \n, if i reach end of buffer first, put whats in buffer into string buffer,
// repeat
buffering:
for (;;) {
if (buffersize == 0) {
fill();
if (buffersize == 0) {
break;
}
}
for (int i = 0; i < buffersize; i++) {
if (buffer[bufferoffset + i] == '\n') {
if (i > 0) { // if \n is first char in buffer, leave the string buffer empty
if (s == null) { s = new StringBuffer(); }
s.append(new String(buffer, bufferoffset, i, "UTF-8"));
}
bufferoffset += i+1;
buffersize -= i+1;
break buffering;
}
}
// We didn't find \n, read the whole buffer into string buffer
if (s == null) { s = new StringBuffer(); }
s.append(new String(buffer, bufferoffset, buffersize, "UTF-8"));
buffersize = 0;
}
if (s == null) {
return null;
} else {
return s.toString();
}
}
/**
DataInput interface
*/
public void readFully(byte[] b) throws IOException {
readFully(b, 0, b.length);
}
public void readFully(byte[] b, int off, int len) throws IOException
{
while (len > 0) {
int read = read(b, off, len);
len -= read;
off += read;
if (read == 0) {
throw new EOFException("End of file reached");
}
}
}
public int skipBytes(int n) throws IOException {
seek(getPosition() + n);
return n;
}
public boolean readBoolean() throws IOException {
return (readByte() != 0);
}
public byte readByte() throws IOException {
byte[] b = new byte[1];
readFully(b, 0, 1);
return b[0];
}
public int readUnsignedByte() throws IOException {
return (int)readByte();
}
public short readShort() throws IOException {
byte[] b = new byte[2];
readFully(b, 0, 2);
return (short)((b[0] << 8) | (b[1] & 0xff));
}
public int readUnsignedShort() throws IOException {
byte[] b = new byte[2];
readFully(b, 0, 2);
return (((b[0] & 0xff) << 8) | (b[1] & 0xff));
}
public char readChar() throws IOException {
return (char)readShort();
}
public int readInt() throws IOException {
byte[] b = new byte[4];
readFully(b, 0, 4);
return (((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16) | ((b[2] & 0xff) << 8) | (b[3] & 0xff));
}
public long readLong() throws IOException {
byte[] b = new byte[8];
readFully(b, 0, 8);
return (((long)(b[0] & 0xff) << 56) | ((long)(b[1] & 0xff) << 48) |
((long)(b[2] & 0xff) << 40) | ((long)(b[3] & 0xff) << 32) |
((long)(b[4] & 0xff) << 24) | ((long)(b[5] & 0xff) << 16) |
((long)(b[6] & 0xff) << 8) | ((long)(b[7] & 0xff)));
}
public float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
public double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
public String readUTF() throws IOException {
int len = readUnsignedShort();
byte[] bytes = new byte[len+2];
bytes[0] = (byte)((len >> 8) & 0xFF);
bytes[1] = (byte)(len & 0xFF);
readFully(bytes, 2, len);
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
return dis.readUTF();
}
public static void main(String[] args) throws IOException {
RandomAccessFileReader f = new RandomAccessFileReader(new File(args[0]));
long pos0 = f.getPosition();
for (int i = 0; i < 5; i++) {
System.out.println(f.readLine());
}
System.out.println("=============");
long pos1 = f.getPosition();
System.out.println("pos: " + pos1);
for (int i = 0; i < 5; i++) {
System.out.println(f.readLine());
}
System.out.println("=============");
f.seek(pos1);
for (int i = 0; i < 5; i++) {
System.out.println(f.readLine());
}
System.out.println("=============");
f.seek(pos0);
for (int i = 0; i < 5; i++) {
System.out.println(f.readLine());
}
long pos2 = f.getPosition();
System.out.println("=============");
System.out.println(f.readLine());
f.seek(pos2);
System.out.println(f.readLine());
f.close();
}
};
© 2015 - 2025 Weber Informatics LLC | Privacy Policy