gpt4 book ai didi

java - Windows 7 中的 WatchService 不起作用

转载 作者:可可西里 更新时间:2023-11-01 09:59:13 33 4
gpt4 key购买 nike

此代码在 Linux 中运行良好,但在 Windows 7 中运行不佳:要获取文件内容更新,我必须单击输出文件。诀窍在哪里?

我正在使用 Windows 7 prof,NetBeans IDE 8.0 RC1(内部版本 201402242200)已更新到版本 NetBeans 8.0 Patch 1.1,JDK 1.8

package watchfilethreadmod;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardWatchEventKinds.*;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class WatchFileThreadMod {

static class WatchFile {

String fileName;
long lastFilePos;
RandomAccessFile file;

public WatchFile(String _fileName, RandomAccessFile _file) {
fileName = _fileName;
lastFilePos = 0;
file = _file;
}
}

public static void shutDownListener(Thread thread) {
Thread thr = thread;
if (thr != null) {
thr.interrupt();
}
}

private static class MyWatchQueueReader implements Runnable {

/**
* the watchService that is passed in from above
*/
private WatchService myWatcher;
public ArrayList<WatchFile> threadFileToWatch;
public String dirPath;

public MyWatchQueueReader(String _dirPath, WatchService myWatcher, ArrayList<WatchFile> _threadFileToWatch) {
this.myWatcher = myWatcher;
this.threadFileToWatch = _threadFileToWatch;
this.dirPath = _dirPath;

}

private void openFile(WatchFile obj) {

try {
System.out.println("Open file "+obj.fileName);
obj.file = new RandomAccessFile(dirPath + "/" + obj.fileName, "r");
} catch (FileNotFoundException e) {
obj.file = null;
System.out.println("filename " + obj.fileName + " non trovato");

}
obj.lastFilePos = 0;

}

private void process(WatchEvent evt) {
String thisLine;
ArrayList<WatchFile> auxList = threadFileToWatch;
for (WatchFile obj : auxList) {

if (obj.fileName.equals(evt.context().toString())) {
if (obj.file == null) {
openFile(obj);
}

try {
obj.file.seek(obj.lastFilePos);
} catch (IOException e) {
System.err.println("Seek error: " + e);
}
try {

thisLine = obj.file.readLine();
if ((thisLine == null)&&(evt.kind() == ENTRY_MODIFY)) {
System.out.printf("---> thisLine == null received %s event for file: %s\n",
evt.kind(), evt.context());
obj.file.close();
System.out.println("Close file "+obj.fileName);
openFile(obj);
thisLine = obj.file.readLine();
}

while (thisLine != null) { // while loop begins here
if (thisLine.length() > 0) {
if (thisLine.substring(thisLine.length() - 1).equals("*")) {
obj.lastFilePos = obj.file.getFilePointer();
System.out.println(obj.fileName + ": " + thisLine);
}
}
thisLine = obj.file.readLine();
} // end while
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
}
}

}

/**
* In order to implement a file watcher, we loop forever ensuring
* requesting to take the next item from the file watchers queue.
*/
@Override
public void run() {
try {
// get the first event before looping
WatchKey key = myWatcher.take();
while (key != null) {
// we have a polled event, now we traverse it and
// receive all the states from it
for (WatchEvent event : key.pollEvents()) {
WatchEvent.Kind eventType = event.kind();
if (eventType == OVERFLOW) {
continue;
}
process(event);
}
key.reset();
key = myWatcher.take();
}
} catch (InterruptedException e) {
ArrayList<WatchFile> auxList = threadFileToWatch;
for (WatchFile obj : auxList) {
if (obj.file != null) {
try {
obj.file.close();
System.out.println("chiusura file " + obj.fileName);
} catch (IOException ex) {
System.out.println("errore in chiusura file");
Logger.getLogger(WatchFileThreadMod.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
//e.printStackTrace();
}
System.out.println("Stopping thread");
}
}

public static void main(String[] args) throws Exception {
// get the directory we want to watch, using the Paths singleton class
//Path toWatch = Paths.get(DIRECTORY_TO_WATCH);
ArrayList<WatchFile> fileToWatch = new ArrayList<>();

String filename;
RandomAccessFile file;
fileToWatch.add(new WatchFile("EURUSD.rlt", new RandomAccessFile(args[0] + "/EURUSD.rlt", "r")));

filename = "EURCHF2.rlt";
try {
file = new RandomAccessFile(args[0] + "/" + filename, "r");
} catch (FileNotFoundException e) {
file = null;
System.out.println("filename " + filename + " non trovato");
}
fileToWatch.add(new WatchFile(filename, file));
fileToWatch = fileToWatch;

Path toWatch = Paths.get(args[0]);
if (toWatch == null) {
throw new UnsupportedOperationException("Directory not found");
}

// Sanity check - Check if path is a folder
try {
Boolean isFolder = (Boolean) Files.getAttribute(toWatch,
"basic:isDirectory", NOFOLLOW_LINKS);
if (!isFolder) {
throw new IllegalArgumentException("Path: " + toWatch + " is not a folder");
}
} catch (IOException ioe) {
// Folder does not exists
ioe.printStackTrace();
}

// make a new watch service that we can register interest in
// directories and files with.
WatchService myWatcher = toWatch.getFileSystem().newWatchService();

// start the file watcher thread below
MyWatchQueueReader fileWatcher = new MyWatchQueueReader(args[0], myWatcher, fileToWatch);
Thread processingThread = new Thread(fileWatcher, "FileWatcher");
processingThread.start();

toWatch.register(myWatcher, ENTRY_CREATE, ENTRY_MODIFY);
}
}

编辑:根据要求减少代码。

编辑2:文件路径

enter image description here

编辑 3: 我用来写入数据的 Metatrader 代码

#property strict

int file_handle;
string InpFileName = _Symbol + ".rlt"; // File name
input string InpDirectoryName = "Data"; // Folder name

int OnInit()
{
ResetLastError();
file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_SHARE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
if(file_handle == INVALID_HANDLE) {
PrintFormat("Failed to open %s file, Error code = %d", InpFileName, GetLastError());
ExpertRemove();
}
return INIT_SUCCEEDED;
}

void OnTick()
{
// file_handle = FileOpen(InpDirectoryName + "//" + InpFileName, FILE_SHARE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
// Datetime), Bid, Volume
// string s = FileRead()
string s = TimeToStr(TimeGMT()) + "|" + Bid + "|" + Volume[0];
FileWriteString(file_handle, s + "|*\r\n");
FileFlush(file_handle);
//FileClose(file_handle);

}

void OnDeinit(const int reason)
{
FileClose(file_handle);
}

编辑 4:截屏视频以更好地展示我的问题:只有当我点击输出文件时数据才会更新

Watch Service does not update

最佳答案

首先,一个前提:我主要是为 WatchService 的 future 用户回答这个问题,他们(像我一样)可能会遇到这个问题(即在某些系统上,事件在他们发出信号后发出信号)发生)。

问题是这个特性在 Java 中的实现是本地的,所以它依赖于平台(看看 https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html ,在“平台依赖性”部分下)。

特别是,在 Windows 7(和 MacOSX afaict)上,实现使用轮询从文件系统检索更改,因此您不能依赖来自 WatchService 的通知的“活跃度”。通知最终会发出信号,但无法保证何时会发生。我对这个问题没有严格的解决方案,但经过大量试验和错误后,我可以描述对我有用的方法:

首先,当写入已注册(即“已观看”)的文件时,我会尝试每次都刷新内容并更新文件上的“最后修改”属性,例如:

try (FileWriter writer = new FileWriter(outputFile)) {
writer.write("The string to write");
outputFile.setLastModified(System.currentTimeMillis());
writer.flush();
}

其次,我尝试从代码“触发”刷新(我知道这不是好的代码,但在这种情况下,我很高兴它在 99% 的时间内都有效)

Thread.sleep(2000);
// in case I've just created a file and I'm watching the ENTRY_CREATE event on outputDir
outputDir.list();

或(如果在 outputDir 中的特定文件上观看 ENTRY_MODIFY)

Thread.sleep(2000);
outputFile.length();

在这两种情况下,sleep 调用只是简单地为触发 WatchService 的机制“提供时间”,即使 2 秒可能比它长得多是需要的。

关于java - Windows 7 中的 WatchService 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24306875/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com