英文:
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文件提供)。
未能奏效的方法:
- Java的Watcher服务 不起作用,我认为是因为操作系统从未收到文件更改的通知(修改时间保持不变,文件大小保持恒定)。我尝试过 - 它从未触发过。嗯,算了!
- 在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:
- 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!
- Setting a
mark()
andreset()
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 毫秒)
方法。
该程序还会显示文件被修改的时间(不准确(+- 毫秒))。
输出:
英文:
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 :
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论