Java RandomAccessFile.java under linux not working correctly

非 Y 不嫁゛ 提交于 2019-12-02 06:54:08

Here is a solution entirely based on Java 7, using the new WatchService infrastructure:

Works, but quite crude...

public final class Baz
{
    public static void main(final String... args)
        throws IOException
    {
        // Get paths to the containing directory and the file we want to spy
        final Path dir = Paths.get("/tmp");
        final Path file = dir.resolve("foo.txt");

        // Get the watch service for our default filesystem
        // We are only interested in modifications and deletions
        final WatchService service = FileSystems.getDefault().newWatchService();
        dir.register(service, StandardWatchEventKinds.ENTRY_MODIFY,
            StandardWatchEventKinds.ENTRY_DELETE);

        // Get a charset decoder -- we will be reading bytes from the file,
        // we will need to decode them to a string
        final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder()
            .onMalformedInput(CodingErrorAction.IGNORE)
            .onUnmappableCharacter(CodingErrorAction.IGNORE);


        try (
            // Open a SeekableByteChannel to the file -- read only
            final SeekableByteChannel channel
                = Files.newByteChannel(file, StandardOpenOption.READ);
        ) {
            long oldSize;
            while (true) {
                // Get the current size of our file
                oldSize = channel.size();
                try {
                    // Grab a key
                    final WatchKey key = service.poll(1L, TimeUnit.SECONDS);
                    if (key == null) // No events...
                        continue;

                    for (final WatchEvent<?> e: key.pollEvents()) {
                        @SuppressWarnings("unchecked")
                        final WatchEvent<Path> event = (WatchEvent<Path>) e;

                        // What kind of event, to whom it applies
                        final WatchEvent.Kind<Path> kind = event.kind();
                        final Path context = dir.resolve(event.context());

                        // If not to us, we don't care
                        if (!context.equals(file))
                            continue;

                        // If our file has disappeared, exit
                        if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
                            System.err.println("File deleted");
                            System.exit(0);
                        }

                        // OK, so it's a modification, and it is our file: read the tail
                        doRead(oldSize, decoder, channel);
                    }
                    // Reset the key for the next batch of events
                    key.reset();
                } catch (InterruptedException e) {
                    // service.poll() interrupted: get out
                    break;
                }
            }
        }
    }

    private static void doRead(final long oldSize, final CharsetDecoder decoder,
        final SeekableByteChannel channel)
        throws IOException
    {
        final long newSize = channel.size();
        if (newSize <= oldSize)
            return;
        final int bufsize = (int) (newSize - oldSize);
        final ByteBuffer buf = ByteBuffer.allocate(bufsize);
        channel.position(oldSize).read(buf);
        buf.rewind();
        decoder.reset();
        System.out.println(decoder.decode(buf).toString());
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!