Skip to content

Instantly share code, notes, and snippets.

@dchekmarev
Created December 18, 2013 12:44
Show Gist options
  • Save dchekmarev/8021713 to your computer and use it in GitHub Desktop.
Save dchekmarev/8021713 to your computer and use it in GitHub Desktop.
allows to seek to any line in the file
import com.google.common.primitives.Longs;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
public static class LineReader {
private final File file;
private final long offsets[];
private final static int BUFFER_SIZE = 1024;
public LineReader(File file) throws IOException {
this.file = file;
List<Long> offsetsList = new ArrayList<>();
try (SeekableByteChannel sbc = Files.newByteChannel(file.toPath())) {
byte[] buf = new byte[BUFFER_SIZE];
long offset = 0;
offsetsList.add(0L);
while (sbc.position() < sbc.size()) {
ByteBuffer dst = ByteBuffer.wrap(buf);
sbc.read(dst);
InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(buf));
int processedOffset = 0;
while (reader.ready()) {
Character ch = (char) reader.read();
int length = ch.toString().getBytes().length;
offset += length;
processedOffset += length;
if (ch == '\n') {
offsetsList.add(offset);
}
if (processedOffset > BUFFER_SIZE - 10) {
sbc.position(offset);
break;
}
}
}
}
offsets = Longs.toArray(offsetsList);
}
public int getLinesCount() {
return offsets.length;
}
public String getLine(int line) throws IOException {
try (SeekableByteChannel sbc = Files.newByteChannel(file.toPath())) {
long expectedSize = (line < offsets.length - 1 ? offsets[line + 1] : sbc.size()) - offsets[line];
byte[] buf = new byte[(int) expectedSize];
ByteBuffer dst = ByteBuffer.wrap(buf);
sbc.position(offsets[line]);
sbc.read(dst);
BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf)));
return br.readLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment