Get the tail of a file (the last 10 lines)
Obviously the tail of the file is harder to do. This is a much more challenging situation than getting the first 10 lines. You have chosen a system that requires complicated byte manipulation to get bytes in to chars, and I don't believe the system will work for non-ascii files where the character encoding of the data may have a second-byte of 0x0A causing a mis-parse of a new-line.

For simplicity sake I would still recommend you use a forward cursor, and a circular buffer. This will work for all files regardless of the size, but the performance will be related to the size. On my system though, even 20MB files were done within moments (0.3 seconds according to the bash 'time' command). So that are not too large (a couple of megabytes), and is easy:

String[] lines = new String[10];
int count = 0;
String line = null;
while ((line = bufferedReader.readLine()) != null) {
    lines[count % lines.length] = line;
    count++;
}


That will load as many as possible lines in to the lines array, limited to 10. It will have the 10-most-recent lines.

Then you can dump those with:

int start = count - 10;
if (start &lt; 0) {
    start = 0;
}

for (int i = start; i &lt; count; i++) {
    System.out.println(lines[i % lines.length];
}


The above code will always work, but for larger files will be slow.

For practical purposes though, I don't believe you will run in to problems, and you should be fine.

I worked a little Java 8 in to the following code as well. Consider the RingBuffer class which allows you to collect the data in to it:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;


public class Tail {

    private static final class RingBuffer {
        private final int limit;
        private final String[] data;
        private int counter = 0;

        public RingBuffer(int limit) {
            this.limit = limit;
            this.data = new String[limit];
        }

        public void collect(String line) {
            data[counter++ % limit] = line;
        }

        public List&lt;String&gt; contents() {
            return IntStream.range(counter &lt; limit ? 0 : counter - limit, counter)
                    .mapToObj(index -&gt; data[index % limit])
                    .collect(Collectors.toList());
        }

    }

    public static final List&lt;String&gt; tailFile(final Path source, final int limit) throws IOException {

        try (Stream&lt;String&gt; stream = Files.lines(source)) {
            RingBuffer buffer = new RingBuffer(limit);
            stream.forEach(line -&gt; buffer.collect(line));

            return buffer.contents();
        }

    }

    public static void main(String[] args) throws IOException {
        tailFile(Paths.get(args[0]), 10).forEach(line -&gt; System.out.println(line));
    }
}