src/main/java/com/github/davidmoten/rx/FileObservable.java
public final static Observable<byte[]> tailFile(File file, long startPosition,
            long sampleTimeMs, int chunkSize, Observable<?> events) {
        Preconditions.checkNotNull(file);
        return sampleModifyOrOverflowEventsOnly(events, sampleTimeMs)
                // tail file triggered by events
                .lift(new OperatorFileTailer(file, startPosition, chunkSize));
    }
public final static Observable<byte[]> tailFile(File file, long startPosition,
            long sampleTimeMs, int chunkSize, Observable<?> events) {
        Preconditions.checkNotNull(file);
        return sampleModifyOrOverflowEventsOnly(events, sampleTimeMs)
                // tail file triggered by events
                .lift(new OperatorFileTailer(file, startPosition, chunkSize));
    }
Returns an {@link Observable} that uses given given observable to push
modified events to an observable that reads and reports new sequences of
bytes to a subscriber. The NIO {@link WatchService} MODIFY and OVERFLOW
events are sampled according to <code>sampleTimeMs</code> so that lots of
discrete activity on a file (for example a log file with very frequent
entries) does not prompt an inordinate number of file reads to pick up
changes. File create events are not sampled and are always passed
through.

@param file
the file to tail
@param startPosition
start tailing file at position in bytes
@param sampleTimeMs
sample time in millis for MODIFY and OVERFLOW events
@param chunkSize
max array size of each element emitted by the Observable. Is
also used as the buffer size for reading from the file. Try
{@link FileObservable#DEFAULT_MAX_BYTES_PER_EMISSION} if you
don't know what to put here.
@param events
trigger a check for file changes. Use
{@link Observable#interval(long, TimeUnit)} for example.
@return observable of byte arrays