我想从另一个应用程序/进程正在编写的文件中读取。
我在另一个问题中找到的这段代码完成了这项工作:它在写入文件时读取文件,只读取新内容。
即使没有数据添加到文件中,也会消耗大量CPU的问题。如何优化此代码?
要添加的另一件事是,我尝试编写的整个程序实时读取文件并处理其内容。所以这意味着thread.sleep或计时器将暂停我的整个程序。我正在寻找的理想改进不是等待几秒钟,而是为了某个事件发生=> 添加了新数据。这可能吗?
public class FileReader {
public static void main(String args[]) throws Exception {
if(args.length>0){
File file = new File(args[0]);
System.out.println(file.getAbsolutePath());
if(file.exists() && file.canRead()){
long fileLength = file.length();
readFile(file,0L);
while(true){
if(fileLength<file.length()){
readFile(file,fileLength);
fileLength=file.length();
}
}
}
}else{
System.out.println("no file to read");
}
}
public static void readFile(File file,Long fileLength) throws IOException {
String line = null;
BufferedReader in = new BufferedReader(new java.io.FileReader(file));
in.skip(fileLength);
while((line = in.readLine()) != null)
{
System.out.println(line);
}
in.close();
}
}
&#13;
答案 0 :(得分:1)
我正在寻找的理想改进不是等待几秒钟,而是 对于某个事件的发生=&gt;添加了新数据。这可能吗?
最佳解决方案:数据推送:
产生内容的应用程序应通知其他应用程序,因为它可能会读取内容。
您可以使用任何可在两个不同应用程序之间传达信息的渠道。
例如,通过使用编写器更新的特定文件来通知要读取的新内容
作者可以在此文件中写入/覆盖更新日期,只有在此日期之后没有读取任何内容的情况下,读者才会读取数据文件。
更强大的方式但是有更多的开销可能会从阅读器方面暴露通知服务
为什么不使用REST服务
通过这种方式,作者可以在新内容准备就绪时通过服务通知读者。
要添加的另一件事,我试图写的整个程序读取了一个 实时归档并处理其内容。所以这意味着 thread.sleep或计时器将暂停我的整个程序。
解决方案解决方案:由特定线程执行的数据提取:
你可能有一个多核CPU
因此,创建一个单独的线程来读取生成的文件,以允许应用程序的其他线程可以运行
此外,您还可以执行一些定期暂停:Thread.sleep()
以优化阅读主题完成的核心使用。
它可能看起来像:
Thread readingThread = new Thread(new MyReadingProcessing());
readingThread.start();
其中MyReadingProcessing
是Runnable
:
public class MyReadingProcessing implements Runnable{
public void run(){
while (true){
readFile(...);
try{
Thread.sleep(1000); // 1 second here but choose the deemed reasonable time according the metrics of your producer application
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
}
if (isAllReadFile()){ // condition to stop the reading process
return;
}
}
}
}
答案 1 :(得分:0)
而不是繁忙的等待循环使用WatchService更改目录条目。
Path path = Paths.get("...");
try (WatchService watchService =
path.getFileSystem().newWatchService()) {
WatchKey watchKey = path.register(watchService,
StandardWatchEventKinds.ENTRY_MODIFY);
for (;;) { // watchKey.poll with timeout, or take, blocking
WatchKey taken = watchService.take();
for (WatchEvent<?> event : taken.pollEvents()) {
Path changedPath = (Path) event.context();
if (changedPath.equals(path)) {
...
}
}
boolean valid = taken.reset();
if (!valid) {
... unregistered
}
}
}
请注意,上述内容必须适用于使用民意调查或拍摄。