JAVA monitors and obtains log file changes (new)

JAVA monitors and obtains log file changes (new)

Use JDK7 + (have not been before 1.7 !?) The tool class java.nio.file.WatchService is
written to monitor the new content of the log file (only the new content can be detected and acquired !? The middle can not be read by hand! Ha! )
To configure directories and files!

Source code:

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;

/**
 * 监控文件变化
 * @author YL
 **/
public class FileWatcher {

    public static void main(String[] args) throws IOException, InterruptedException {
        // 监控的目录
        String filePath = "C:\\project\\imony_abroad\\logs\\";
        // 要监控的文件
        String fileName = "spring.log";

        FileWatcher.watcherLog(filePath, fileName, System.out::println);
    }

    /**
     * 文件监控
     * 同步调用会阻塞
     * @param filePath
     * @param fileName
     * @param consumer
     * @throws IOException
     * @throws InterruptedException
     */
    public static void watcherLog(String filePath, String fileName, Consumer<String> consumer) throws IOException, InterruptedException {
        WatchService watchService = FileSystems.getDefault().newWatchService();

        Paths.get(filePath).register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
                StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);
		// 文件读取行数
        AtomicLong lastPointer = new AtomicLong(0L);
        do {
            WatchKey key = watchService.take();
            List<WatchEvent<?>> watchEvents = key.pollEvents();
            watchEvents.stream().filter(
                    i -> StandardWatchEventKinds.ENTRY_MODIFY == i.kind()
                            && fileName.equals(((Path) i.context()).getFileName().toString())
            ).forEach(i -> {
                if (i.count() > 1) {
                    // "重复事件"
                    return;
                }

                File configFile = Paths.get(filePath + "/" + i.context()).toFile();
                StringBuilder str = new StringBuilder();
                // 读取文件
                lastPointer.set(getFileContent(configFile, lastPointer.get(), str));

                if (str.length() != 0 ) {
                    consumer.accept(str.toString());
                }
            });
            key.reset();
        } while (true);
    }

    /**
     * beginPointer > configFile 时会从头读取
     * @param configFile
     * @param beginPointer
     * @param str 内容会拼接进去
     * @return 读到了多少字节, -1 读取失败
     */
    private static long getFileContent(File configFile, long beginPointer, StringBuilder str) {
        if (beginPointer < 0) {
            beginPointer = 0;
        }
        RandomAccessFile file = null;
        boolean top = true;
        try {
            file = new RandomAccessFile(configFile, "r");
            if (beginPointer > file.length()) {
                return 0;
            }
            file.seek(beginPointer);
            String line;
            while ((line = file.readLine()) != null) {
                if (top) {
                    top = false;
                } else {
                    str.append("\n");
                }
                str.append(new String(line.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
            }
            return file.getFilePointer();
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        } finally {
            if (file != null) {
                try {
                    file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Published 17 original articles · won 24 · views 280,000 +

Guess you like

Origin blog.csdn.net/qq_22956867/article/details/102552830