How to monitor a text file in java - java

I am making an application that will display a gui and read a text file. When the contents of the text file changes it will execute changes to the gui. However i need the gui to constantly be reading and checking the textfile for changes. I have tried thread.sleep() which just takes control and no code works other than the loop. After looking around i found reference to swing timers and running in new threads that weren't the EDT. This stuff is lost on me and I can find no way to implement it. Any help would be appreciated.
public void run() {
initComponents();
while(true){System.out.println("ok");
try {
try {
File myFile = new File("C:\\Users\\kyleg\\OneDrive\\Documents\\123.txt");
System.out.println("Attempting to read from file in: "+myFile.getCanonicalPath());
Scanner input = new Scanner(myFile);
String in = "";
in = input.nextLine();
System.out.println(in);
switch(in){
case("1"):
break;
case("2"):
break;
case("3"):
break;
}
} catch (IOException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

This is just a simple code for file monitoring, hope it can help you.
File f = new File("Path_to_the_file");
new Thread(new Runnable() {
#Override
public void run() {
long l = f.lastModified();
String s = "";
while (true) {
if (f.lastModified() == l) {
System.out.print();
} else {
try {
Scanner sc = new Scanner(f);
s = "";
while (sc.hasNext()) {
s += sc.nextLine();
s += "\n";
jTextArea1.setText(s);
}
System.out.println(false);
l = f.lastModified();
sc.close();
} catch (FileNotFoundException ex) {
System.out.println(ex);
}
}
}
}
}).start();

Related

Multi-threaded read from file and execute runnable

WHAT?
I am trying to build a tool that will reads a text file and publishes the text, after doing some string transformation.
HOW?
The tool reads the file line by line and populates a LinkedBlockingQueue. At the same time I initiate multiple threads that will then take a message each from the LBQ, do some processing and publish them.
Main
private static LinkedBlockingQueue<String> lbQueue = new LinkedBlockingQueue<>();
private static Boolean keepPublisherActive = Boolean.TRUE;
public static void main(String[] args) {
try {
tool.initMessagePublish();
tool.searchUsingScanner();
} catch (Exception ex) {
logger.error("Exception in Tool Main() " + ex.toString());
throw ex;
}
}
File Reader
private void searchUsingScanner() {
Scanner scanner = null;
try {
scanner = new Scanner(new File(LOG_FILE_PATH));
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (StringUtils.isNotBlank(line)) {
lbQueue.offer(line);
}
}
} catch (Exception e) {
logger.error("Error while processing file: " + e.toString());
} finally {
try {
if (scanner != null) {
scanner.close();
}
// end thread execution
keepPublisherActive = false;
} catch (Exception e) {
logger.error("Exception while closing file scanner " + e.toString());
throw e;
}
}
}
Multi-threaded Publisher
private void initMessagePublish() throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(6);
try {
while (keepPublisherActive || lbQueue.getSize() > 0) {
service.execute(messagePublisher); // messagePublisher implements Runnable
}
} catch (Exception ex) {
logger.error("Multi threaded message publish failed " + ex.toString());
throw ex;
} finally {
service.shutdown();
}
}
THE PROBLEM
The intention behind calling initMessagePublish() fist is that the publisher need not wait for all lines to be read from the file before starting to publish. It should start publishing as soon as something becomes available in the LBQ.
But with the current implementation, the control never comes out of the initMessagePublish and start searchUsingScanner. How do I solve this? Basically, the two methods should execute parallely.
Just start messagePublisher in a new Thread (Line no #5 in Main class):
new Thread(()->tool.initMessagePublish()).start();
It should solve your problem.

Running python script from java and sending input/output

I am writing a java program that will need to run a python script.
The script will print output which will java need to read to know the progress of the script.
To be able to pause the script while running I want it to ask for input once in a while, only when java give it input the script will keep going.
Here is my Java method:
private static void sevenTry(String[] strCommands) throws IOException {
Object oLock1 = new Object();
Object oLock2 = new Object();
ProcessBuilder pBuilder = new ProcessBuilder(strCommands);
pBuilder.redirectErrorStream(true);
Process proc = pBuilder.start();
Thread tReader = new Thread() {
#Override
public void run() {
System.out.println("~~tReader starting~~");
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
synchronized (oLock1) {
try {
String line = reader.readLine();
while (line != null && !line.trim().equals("--EOF--")) {
System.out.println("Stdout: " + line);
if (line.trim().equals("--INPUT--")) {
synchronized (oLock2) {
oLock2.notify();
}
oLock1.wait();
}
line = reader.readLine();
}
} catch (IOException e) {
System.out.println("tReader: " + e.getMessage());
} catch (InterruptedException e) {
System.out.println("tReader: " + e.getMessage());
} catch (Exception e) {
System.out.println("tReader: " + e.getMessage());
}
}
System.out.println("~~tReader end~~");
synchronized (oLock2) {
oLock2.notify();
}
}
};
Thread tWriter = new Thread() {
#Override
public void run() {
System.out.println("~~tWriter starting~~");
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
String line, input;
Scanner scan = new Scanner(System.in);
synchronized (oLock2) {
try {
oLock2.wait();
} catch (InterruptedException e1) {
System.out.println("tWriter: " + e1.getMessage());
}
}
while (tReader.isAlive()) {
synchronized (oLock1) {
System.out.println("Java: insert input");
scan.hasNext();
input = scan.nextLine();
try {
writer.write(input + "\n");
writer.flush();
} catch (IOException e) {
System.out.println("tWriter: " + e.getMessage());
}
oLock1.notify();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
System.out.println("tWriter: " + e1.getMessage());
}
}
System.out.println("~~tWriter end~~");
}
};
tReader.start();
tWriter.start();
System.out.println("~~everything submitted~~");
try {
tReader.join();
tWriter.join();
System.out.println("~~finish~~");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This is my python script:
# coding=utf-8
import sys
print '1'
print '--INPUT--'
inum = sys.stdin.readline()
print '2'
print '--EOF--'
I tried running my code
sevenTry("python", "C:\\Testing.py");
but on java side it get stuck inside tReader at line:
String line = reader.readLine();
The program does work if i take out the input line from the python file
inum = sys.stdin.readline()
Using
inum = raw_input()
still bring up the same problem (im using python 2.7)
The most confusing part here that i even tried to test this with a java file (instead of python)
sevenTry("java", "-classpath", "C:\\class", "CheckCMD");
and it worked even with the input lines
import java.util.Scanner;
public class CheckCMD {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String line;
System.out.println("1");
System.out.println("--INPUT--");
in.hasNext();
line = in.nextLine();
System.out.println("2");
System.out.println("--EOF--");
}
}
As you may have noticed, this is a problem related to Python.
As described in https://unix.stackexchange.com/questions/182537/write-python-stdout-to-file-immediately,
" when process STDOUT is redirected to something other than a terminal, then the output is buffered into some OS-specific-sized buffer (perhaps 4k or 8k in many cases)."
So, you need to call sys.stdout.flush() after each invoke to print.
Or, as a better option, you can change the default behaviour for the process, using the -u param, to get unbuffered output.

Why won't my program remove a string from the ArrayList

My code is a basic file creator and manager. The main way I organise all the files are in a directory text file. I import it into an array so the program can access it. My delete button doesn't remove the string from the ArrayList. How can i fix this?
//This part initialises the code and imports the array
private void startActionPerformed(java.awt.event.ActionEvent evt) {
ArrayList<String> directory = new ArrayList();
String content1;
try {
content1 = new String(Files.readAllBytes(Paths.get("directory.txt")));
output.setText(content1);
directory.add(content1);
refresh();
} catch (IOException ex) {
Logger.getLogger(filemanagerUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
//This allows me to refresh the output text area
private void refresh() {
String content = "";
for (int i = 0; i < directory.size(); i++) {
content = content + directory.get(i) + "\n";
}
try {
Files.write(Paths.get("directory.txt"), directory);
} catch (IOException ex) {
Logger.getLogger(filemanagerUI.class.getName()).log(Level.SEVERE, null, ex);
}
output.setText(content);
System.out.println(directory);
}
//This deletes the file from the directory and the actual file
private void deleteActionPerformed(java.awt.event.ActionEvent evt) {
directory.remove(input.getText());
String fileDelete = input.getText();
directory.remove(input.getText());
Path deletefile = (Paths.get(fileDelete + ".txt"));
try {
Files.delete(deletefile);
} catch (IOException ex) {
Logger.getLogger(filemanagerUI.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Files.write(Paths.get("directory.txt"), directory);
} catch (IOException ex) {
Logger.getLogger(filemanagerUI.class.getName()).log(Level.SEVERE, null, ex);
}
refresh();
}
Maybe you have the file open when you debugging it. Make sure the program can access it

can i make my app (open with) windows menu with java (need examples)

i need some example to make my app as default text editor in java
(i mean when I open the text file opens with my program)
How can I do that with Java ??
I finally found the answer after many tests When i open the text file with my app from open with menu in windows
public static void main(String[] args) {
FileReader file_reader = null;
try {
new Notepad().setVisible(true);
file_reader = new FileReader(args[0]);
BufferedReader br = new BufferedReader(file_reader);
String temp = "";
while (br.ready())
{
int c = br.read();
temp = temp+ (char)c;
}
myarea.setText(temp);
br.close();
file_reader.close();
textContent = myarea.getText();
} catch (FileNotFoundException ex) {
Logger.getLogger(Notepad.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Notepad.class.getName()).log(Level.SEVERE, null, ex);
} finally {
}
}
you must make your app exe

Java Thread drives CPU to 100%

I have rewritten this many times but I could not find a solution to this problem for a while. Some other Class writes gps.log file with lines like:
2014-09-02 10:23:13 35.185604 33.859077
2014-09-02 10:23:18 35.185620 33.859048
I am trying to read the last line of the file and update a text field in the user interface. The Thread below is overdriving the CPU into 85-100%.
I keep the file very tiny (100 lines - < 5KB). I have been working with CSV for a long time, and I think reading this file every 3 seconds should not have this footprint on the CPU. Although I have been reading huge CSV files in the past it is the first time I have this issue now that I try to update the User Interface every couple seconds. Am I doing something wrong with how I am updating the text field? Any ideas?
Thanks for looking.
new Thread(new Runnable() {
public void run() {
while (true) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
try {
try { Thread.sleep(3000); } catch (Exception e) { }
BufferedReader gpslog = new BufferedReader(new FileReader("log/gps.log"));
String line = "";
String lastLine = "";
int i=0;
while (line != null) {
i++;
lastLine = line;
line = gpslog.readLine();
}
//System.out.println(lastLine);
gpslog.close();
if (lastLine != null) { txtGPSStatus.setText(lastLine); }
//If more than 100 gps entries, flush the file
if (i>100) {
PrintWriter writer = new PrintWriter("log/gps.log");
writer.close();
}
} catch (IOException e1) {
log.error(e1);
}
}
});
}
}
}).start();
Move
try { Thread.sleep(3000); } catch (Exception e) { }
so it is just after
while(true) {
Then you will run, wait 3 secs, run, etc.
You should get a clear idea of what should be done by the background thread and what the UI thread is for!
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
public void run() {
try {
while (true) {
updateLog();
Thread.sleep(3000);
}
} catch (InterruptedException ex) {
// restore interruption flag
Thread.currentThread().interrupt();
}
}
});
private void updateLog() {
String lastLine = readLastLogLine();
Display.getDefault().syncExec(new Runnable() {
public void run() {
txtGPSStatus.setText(lastLine);
}
});
}

Categories

Resources