host.anzo.commons.io.FileBinaryReader Maven / Gradle / Ivy
package host.anzo.commons.io;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @author xTz
* @since 29.12.2015
*/
@Slf4j
public class FileBinaryReader implements AutoCloseable {
private static final int MAX_NULL_TERMINATED_STRING_LENGTH = 32 * 1024;
private RandomAccessFile roChannel = null;
@SuppressWarnings("unused")
public FileBinaryReader(String path) {
this(Paths.get(path), true);
}
public FileBinaryReader(String path, boolean castException) {
this(Paths.get(path), castException);
}
public FileBinaryReader(Path path) {
this(path, true);
}
@SuppressWarnings("unused")
public FileBinaryReader(Path path, boolean castException) {
try {
roChannel = new RandomAccessFile(path.toString(), "r");
roChannel.order(RandomAccessFile.LITTLE_ENDIAN);
} catch (Exception ex) {
if (castException) {
log.error("Error while opening FileBinaryReader for file {}", path.getFileName(), ex);
}
}
}
public byte[] readB(int size) throws IOException {
final byte[] temp = new byte[size];
readB(temp);
return temp;
}
public void readB(byte[] dst) throws IOException {
roChannel.read(dst);
}
public void readB(byte[] dst, int offset, int len) throws IOException {
roChannel.read(dst, offset, len);
}
public int readCD() throws IOException {
return roChannel.readByte() & 0xFF;
}
public byte readC() throws IOException {
return roChannel.readByte();
}
public boolean readCB() throws IOException {
return readCD() == 1;
}
public short readH() throws IOException {
return (short) (roChannel.readShort() & 0xFFFF);
}
public int readHD() throws IOException {
return roChannel.readShort() & 0xFFFF;
}
public int readD() throws IOException {
return roChannel.readInt();
}
public long readDQ() throws IOException {
return roChannel.readInt() & 0xFFFFFFFFL;
}
public long readQ() throws IOException {
return roChannel.readLong();
}
public int readQD() throws IOException {
return (int) roChannel.readLong();
}
public float readF() throws IOException {
return roChannel.readFloat();
}
public double readFF() throws IOException {
return roChannel.readDouble();
}
/***
* Read null-terminated string
*
* @return reader string
*/
public String readS() throws IOException {
final StringBuilder sb = new StringBuilder();
int charCount = 0;
char ch;
while (charCount < MAX_NULL_TERMINATED_STRING_LENGTH) {
if ((ch = roChannel.readChar()) == 0) {
break;
}
sb.append(ch);
charCount++;
}
return sb.toString();
}
public String readQS() throws IOException {
return readS(readQD() * 2);
}
public final @NotNull String readQSS() throws IOException {
final StringBuilder tb = new StringBuilder();
long size = readQ() * 2;
for (char c; size > 0; size -= 2) {
if ((c = roChannel.readChar()) != 0) {
tb.append(c);
}
}
return tb.toString();
}
public String readS(int size, Charset charset) throws IOException {
final byte[] strBytes = new byte[size];
readB(strBytes);
return new String(strBytes, charset);
}
public String readS(int size) throws IOException {
return readS(size, Charset.defaultCharset());
}
public String readS(long size) throws IOException {
return readS((int) size, Charset.defaultCharset());
}
public void setPosition(int position) throws IOException {
roChannel.getRandomAccessFile().getChannel().position(position);
}
public long getPosition() throws IOException {
return roChannel.getRandomAccessFile().getChannel().position();
}
public long getSize() throws IOException {
return roChannel.getRandomAccessFile().getChannel().size();
}
public boolean hasFile() {
return roChannel != null;
}
public String getPositionHex() throws IOException {
return Long.toHexString(getPosition());
}
public final void skip(int bytes) throws IOException {
readB(bytes);
}
@Override
public void close() {
if (roChannel != null) {
try {
roChannel.close();
}
catch (IOException e) {
log.error("Error while closing FileBinaryReader channel!", e);
}
}
}
}