Java: how to poll a small file over and over to see if it changed? (watching can't work)

huangapple go评论72阅读模式
英文:

Java: how to poll a small file over and over to see if it changed? (watching can't work)

问题

在Java 8+中,轮询/读取一个小的纯ASCII文件以检查其是否更改的开销最小方法是什么?

我有一个设备,它创建了一个模拟文件系统(ev3dev),提供具有状态更新的小型只读文件(例如,一个带有单个Int的position文件表示乐高电机的位置,或者一个带有单个String的status文件表示电机的状态,两者都作为纯ASCII文件提供)。

未能奏效的方法

  1. Java的Watcher服务 不起作用,我认为是因为操作系统从未收到文件更改的通知(修改时间保持不变,文件大小保持恒定)。我尝试过 - 它从未触发过。嗯,算了!
  2. 在BufferedReader上设置mark()reset()以一遍又一遍地读取文件似乎在BufferedReader上不起作用,有没有办法使其工作?

我认为我必须进行轮询:一遍又一遍地(一遍又一遍地,一遍又一遍地)快速读取文件

  • 我可以使用内存映射文件(它会获取更改吗?)

  • 保持所有内容打开并使用mark/reset或类似方法来获取更改?

  • 还是要下定决心,在单独的线程中以1毫秒的循环延迟调用Files.readAllBytes

英文:

What is the least-overhead way in Java 8+ to poll/read a small plain ASCII file to check if it changed?

I have a device that creates a fake filesystem (ev3dev) that provides small read-only files with status updates. (eg. a lego motor's position in a position file with a single Int, or the motor's status in a status file with a single String, both served up as a plain ASCII file)

Things that didn't work:

  1. Java's Watcher service doesn't work, I think because the OS is never notified that the file changed. (the modified time stays the same, and the file size is constant.) I tried -- it never triggers. Oh well!
  2. Setting a mark() and reset() to read the file over and over without creating a new Reader doesn't seem to work on a BufferedReader, are there ways to make it work?

I think I have to poll: quickly read the file over and over (and over. and over!)

  • Can I use a memory-mapped file (will it pick up the changes?)

  • Some way to keep everything open and do a mark/reset or similar to pick up changes?

  • Or just bite the bullet and call Files.readAllBytes in its own thread with a 1ms delay between loops?

答案1

得分: 1

你可以在你的代码中使用RandomAccessFile类。

我的代码:

import java.io.*; //导入RandomAccessFile类
import java.util.*; // Thread.sleep(毫秒)
public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        /*为了增加功能,我还指定了文件修改的时间*/
        System.out.println("输入文件路径:");
        String file_path = scan.nextLine();
        RandomAccessFile f = new RandomAccessFile(file_path, "r");
        int character;
        String Intitalval = "";
        while ((character = f.read()) != -1) {
            Intitalval += (char) character;
        }
        f.seek(0);
        boolean nochange = true;
        while (nochange) {
            String ToCompare = "";
            while ((character = f.read()) != -1) {
                ToCompare += (char) character;
            }

            if (!ToCompare.equals(Intitalval)) {
                nochange = false;
                System.out.println("文件已于 " + java.time.LocalTime.now() + " 修改");
            }
            Thread.sleep(1);
            f.seek(0);
        }
        f.close();
    }
}

正如你所说,你想要一个1毫秒的延迟,我使用了java的Thread.sleep(int 毫秒)方法。

该程序还会显示文件被修改的时间(不准确(+- 毫秒))。

输出:

Java: how to poll a small file over and over to see if it changed? (watching can't work)

英文:

You can use the RandomAccessFile class for your code.

My code :

import java.io.*; //Importing RandomAccessFile Class
import java.util.*; // Thread.sleep(milliseconds)
public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        /*Just To add functionality I have also specified the time at which the file is modified*/
        System.out.println("Input File Path : ");
        String file_path = scan.nextLine();
        RandomAccessFile f = new RandomAccessFile(file_path,"r");
        int character;
        String Intitalval="";
        while ((character = f.read()) != -1) {
            Intitalval+=(char)character;
        }
        f.seek(0);
        boolean nochange = true;
        while (nochange) {
            String ToCompare="";
            while ((character = f.read()) != -1) {
                ToCompare+=(char)character;
            }

            if (!ToCompare.equals(Intitalval)) {
                nochange = false;
                System.out.println("The file has been modified at " + java.time.LocalTime.now());
            }
            Thread.sleep(1);
            f.seek(0);
        }
        f.close();
    }
}

As you said you want a delay of 1 millisecond I have used java Thread.sleep(int milliseconds) method.

The program will also display the time at which the file is modified (not accurate (+- milliseconds)).

Output :

Java: how to poll a small file over and over to see if it changed? (watching can't work)

huangapple
  • 本文由 发表于 2020年7月26日 13:51:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63096565.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定