Last active
December 14, 2015 02:59
-
-
Save hoffrocket/5017996 to your computer and use it in GitHub Desktop.
Buffered FileTailer in scala.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.{File, RandomAccessFile} | |
import java.nio.{ByteBuffer, CharBuffer} | |
import java.nio.charset.Charset | |
/** | |
* Read lines from the end of a file. | |
* | |
* Partial lines that don't terminate with a newline will be lost | |
* Lines bigger than the buffer size will also be lost | |
*/ | |
class FileTailer(val path: String) { | |
val charset = Charset.forName("utf-8") | |
val buffer = ByteBuffer.allocate(8192) | |
var charBuffer: CharBuffer = null | |
val file = { | |
val f = new File(path) | |
val raf = new RandomAccessFile(f, "r") | |
raf.seek(math.max(0, f.length - buffer.capacity)) | |
raf | |
} | |
def readLine: CharSequence = { | |
if (charBuffer == null || !charBuffer.hasRemaining) { | |
buffer.clear | |
file.getChannel.read(buffer) | |
buffer.flip | |
charBuffer = charset.decode(buffer) | |
} | |
var foundNewLine = false | |
charBuffer.mark | |
while (charBuffer.hasRemaining && !foundNewLine) { | |
if (charBuffer.get == '\n') { | |
foundNewLine = true | |
} | |
} | |
if (foundNewLine) { | |
val copy = charBuffer.duplicate | |
copy.limit(copy.position - 1) | |
copy.reset | |
copy | |
} else { | |
null | |
} | |
} | |
def close = file.close | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Apparently, FileInputStream.skip may or may not work for a "variety of reasons" http://docs.oracle.com/javase/6/docs/api/java/io/FileInputStream.html#skip(long)
RandomAccessFile seeks as expected, but the readLine method is unbuffered and doesn't seem to correctly handle unicode.
Inspired by http://stackoverflow.com/questions/4305094/java-reading-strings-from-a-random-access-file-with-buffered-input