java - Watchservice in windows 7 does not work -
this code works fine in linux not in windows 7: file contents update have click on output file. trick?
i using windows 7 prof, netbeans ide 8.0 rc1 (build 201402242200) updated version 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 { /** * watchservice passed in 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; (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 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 implement file watcher, loop forever ensuring * requesting take next item file watchers queue. */ @override public void run() { try { // first event before looping watchkey key = mywatcher.take(); while (key != null) { // have polled event, traverse , // receive states (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; (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 { // directory want watch, using 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 folder try { boolean isfolder = (boolean) files.getattribute(towatch, "basic:isdirectory", nofollow_links); if (!isfolder) { throw new illegalargumentexception("path: " + towatch + " not folder"); } } catch (ioexception ioe) { // folder not exists ioe.printstacktrace(); } // make new watch service can register interest in // directories , files with. watchservice mywatcher = towatch.getfilesystem().newwatchservice(); // start 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); } }
edit: reduced code requested.
edit 2: file path
edit 3: metatrader code using write data
#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 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); }
edit 4: screencast better show issue: data updates when click on output file
first of all, premise : i'm answering question future users of watchservice
, (like me) experience problem (i.e. on systems events signaled way after occur).
the problem implementation of feature in java native, platform-dependant (take @ https://docs.oracle.com/javase/7/docs/api/java/nio/file/watchservice.html, under section 'platform dependencies').
in particular, on windows 7 (and macosx afaict) implementation uses polling retrieve changes filesystem, can't rely on 'liveliness' of notifications watchservice
. notifications signaled, there no guarantees on when happen. don't have rigorous solution problem, after lot of trial , error can describe works me :
first, when writing file registered (i.e. 'watched'), try flush content every time can , update 'last modified' attribute on file, e.g. :
try (filewriter writer = new filewriter(outputfile)) { writer.write("the string write"); outputfile.setlastmodified(system.currenttimemillis()); writer.flush(); }
second, try 'trigger' refresh code (i know it's not code, in case, i'm happy works 99% of time)
thread.sleep(2000); // in case i've created file , i'm watching entry_create event on outputdir outputdir.list();
or (if watching entry_modify
on particular file in outputdir
)
thread.sleep(2000); outputfile.length();
in both cases, sleep
call 'gives time' mechanism underlying watchservice
trigger, though 2 seconds lot more needed.
Comments
Post a Comment