I'm trying to monitor the file content and adding any new line to JTextArea. I created thread, which monitor the file, but when the Scanner object reachs the end of file it stop working. I tried very simple method, which create new Scanner object and read the file from the begin, but it isn't good solution.
It's the version which stop and do nothing :
public class TextAreaThread implements Runnable {
JTextArea text = null;
File file = null;
Scanner read = null;
public TextAreaThread(JTextArea text, File file) {
this.text = text;
this.file = file;
try{
read = new Scanner(file);
}catch(FileNotFoundException e){
JOptionPane.showMessageDialog(null,"Wrong file or file doesn't exist","Error",JOptionPane.ERROR_MESSAGE);
}
}
public void run() {
while(true){
while(read.hasNext())
text.append(read.nextLine()+"\n");
try {
wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The wait method is not what you want here. Try Thread.sleep instead.
Related
I created Simple program for File update throgh java Program
public class AppendToFileExample {
private static final String FILENAME = "TestFile.txt";
public static void main(String[] args) {
BufferedWriter bw = null;
FileWriter fw = null;
try {
String data = " This is new content after edit";
File file = new File(FILENAME);
fw = new FileWriter(file, true);
bw = new BufferedWriter(fw);
bw.write(data);
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Which is working successfully
But Then i tried to do same thing with the help of ServletContextListener but with servlet everything working fine except I have to put Full file path like this
String FILENAME = "C:\\Users\\admin\\workspacetasks\\UpdateText\\TestFile.txt";
With this full path its working fine but its not updating file when i try to pass only file name like this
String FILENAME = "test.txt";
So my question is how to pass file without full path of file..Is there any other way or anything?or any link for reference?
Thank You.
Below is mine ServletContextListener
public class StartupListener implements ServletContextListener {
private static Logger log = Logger.getLogger(StartupListener.class);
#Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("contextInitialized");
UpdateTextFile updateTextFile = new UpdateTextFile();
System.out.println("Before");
updateTextFile.exec();
System.out.println("after");
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
}
and then this will call method in java program that program is here
public class UpdateTextFile
{
private static Logger log = Logger.getLogger(UpdateTextFile.class);
public void exec() {
// String FILENAME = "C:\\Users\\admin\\workspacetasks\\UpdateText\\TestFile.txt";
String FILENAME = "TestFile.txt";
System.out.println("Inside exce ");
BufferedWriter bw = null;
FileWriter fw = null;
try {
String data = "Aloha after edit \n";
System.out.println(data);
File file = new File(FILENAME);
System.out.println(FILENAME);
System.out.println("Before FileWriter");
fw = new FileWriter(file, true);
System.out.println("After FileWriter");
System.out.println("Before BufferedWriter");
bw = new BufferedWriter(fw);
System.out.println("After BufferedWriter");
System.out.println("Before Write Data");
bw.write(data);
System.out.println("After Write Data");
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
If your code doesn't throw any exceptions, the file is definitely being created, just not where you think. A file with a relative path will be created relative to the current working directory of your application, whatever that may be. In the case of a servlet container it certainly won't be anywhere inside the webapp's own directory. For example in Tomcat it might be Tomcat's bin directory.
NB:
Contrary to the now-deleted answer by #SilvanBregy, the CWD of an application doesn't necessarily have anything to do with where its own JAR file is located, and contrary to the comment by #soufrk it has exactly nothing to do with the classpath.
The exists() test and createNewFile() calls are both complete wastes of time. new FileOutputStream() already does that, so you're forcing the system to do it all twice, as well as deleting the file you just created.
You don't need to call getAbsoluteFile() either: the File alone is sufficient.
You do however need to close the BufferedWriter.
Yes its SOLVED.If any one in future have same problem then
just click right on program Run As > Run Configuration > Tomcat 8 on left panel > Arguments and then set Other working directory as you want...
Dont know its correct approach to do but thats what i got..if any one get any other way without changing working directory then please share else if i get any i will post it
I want to write program that stores information about cars. You input for instance brand and owner name for each car in dialog boxes. In the end, a dialog box with information about all cars should be shown by writing the information to a text file and then reading from it to the dialog box. I create a method getInfo which shows the appropriate boxes correctly.
public static void getInfo() {
boolean done = false;
do {
String brand=JOptionPane.showInputDialog(null, "Brand?");
String name=JOptionPane.showInputDialog(null, "Owner?");
if (brand == null) {
done = true;
} else {
String info ="Car: "+brand+" "+"\nOwner: "+name;
String message = " Do you want to input more cars?";
int buttonClicked = JOptionPane.showConfirmDialog(null, message, "", JOptionPane.YES_NO_OPTION);
done = (buttonClicked == JOptionPane.NO_OPTION);
}
} while (!done);
}
public static void main(String[] args) {
getInfo();
}
I am not sure how to add the information to a text file and how to deal with the loops. To write the information to a text file I tried to change the main method to the following
public static void main(String[] args) throws IOException {
try (PrintWriter outstream = new PrintWriter
(new BufferedWriter
(new FileWriter("cars.txt", true)))) {
getInfo();
outstream.println(info);
}
}
What am I missing and how can I implement the functionality?
You can define a BufferedWriter outside of the loop:
File outputFile = new File("path/to/the/file.txt");
if(!outputFile.exists()){
try {
outputFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedWriter bw = null; //this declares a buffer that writes to some stream.
try{
bw = new BufferedWriter(new FileWriter(outputFile,true)); //here we actually create it, and tell it to write to a file stream, directed at the outputFile file.
}catch(IOException e){
e.printStackTrace(); //this is if the file doesn't exist, which shouldn't happen, but we still need to put this here, because better safe than sorry.
}
And then in your loop: after the
String info ="Car: "+brand+" "+"\nOwner: "+name;
do:
String info ="Car: "+brand+" "+"\nOwner: "+name;
try {
bw.write(info);//write the information to the buffer when there's new info.
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
and after exiting the loop, call:
bw.close();
First of all, with every loop you are creating a new instance of info, so you will lose the information from the previous runs.
In your main method you are accessing info, but it should not be known in that scope. What you could do, is to return info from the getInfo() method.
You should then also think about line breaks and so on, but for a first try this should be it.
Try the following:
public static void main() {
boolean done = false;
do {
Info info = getInfo();
storeInfo(info);
done = getDone();
} while (!done);
displayInfo();
}
class Info {
private brand;
private owner;
}
Now you can do single things in each method.
getInfo calls showInputDialog and returns an Info object.
storeInfo stores the Info object to a text file.
getDone calls showInputDialog and returns, if the user wants to quit.
displayInfo opens the text file and shows the info.
The easiest way to implement displayInfo migth be:
void displayInfo() {
// Create a window with TextBox
// Open the text file
// Read the content of the text file and add it to the TextBox
}
For my application, I need to continuously read from a file and the application will proceed on reading 100 from that file. I'm writing to the same line of the file i.e I'm overwriting the file contents. But my program reads the next line in after each iteration of the loop. My code:
public class h{
private int flag=0;
public void scan()
{
String filename="file1.txt";
try{
int i,j;
int nooflines=1;
String textData = new String();
try{
FileReader fr = new FileReader(filename);
BufferedReader textReader = new BufferedReader(fr);
while(flag==0){
textData=textReader.readLine();
if(textData==null){
Thread.sleep(3000);
continue;
}
process(textData);
}
textReader.close();
}catch(InterruptedException e){
System.out.println(e.getMessage());
}
}catch (IOException e){
System.out.println(e.getMessage());
}
}
public void process(String data){
if(data.equals("100")){
System.out.println(data);
flag=1;
}
}
}
So after one iteration my code will be scanning the second line, but the file1.txt is opened using write mode(-w) which erase its contents and writes at the beginning of the file. So how can I edit my program to keep scanning the first line of the file only?
I think this'll do it.
BufferedReader textReader;
while(flag==0){
textReader = new BufferedReader(new FileReader(filename));
textData=textReader.readLine();
if(textData==null){
Thread.sleep(3000);
continue;
}
process(textData);
}
To read your file from the beginning every 3s:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
try(BufferedReader br = new BufferedReader(new FileReader(filename))) {
while(keepReading) {
keepReading = process(br.readLine());
}
}
}
}, 0, 3, TimeUnit.SECONDS); // every 3s
public boolean process(String data) {
// do something
return data != null && !data.equals("100");
}
All, I am trying to read a file which will be written by multiple threads, I am going to use BufferedReader to read that file in a thread.
The code looks like below.
FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader);
String detail;
while ((detail =br.readLine()) != null)
{
...
}
Currently It seems works fine. But I have some questions about it.
If the question sound silly. please don't laugh at me . thanks.
Is it possible that the loop never been broken ? because the other threads are writing into the file.So maybe the readLine() may never return null?
Updated
Let's say there are 3 threads(T1,T2,T3).
T1 and T2 are writer.
T3 is reader.
The code runs in below sequence.
1.The current file lines number is 100.
2.T1 write a line to file.(file lines increase to 101)
3.T3 reads the last line of file(101). next read will get null.
4.T2 append a line to file.(file lines increase to 102)
5.T3 read again....(Does it return null or not? because T2 just added a new line into file before T3 read again.)
Please help to review it .thanks in advance.
Yes, it is possible that the loop will never end (at least until you run out of memory). Here's some code to prove it:
public class test {
public static void main(String[] args) {
// start thread to write to file
new Thread(new Runnable() {
#Override
public void run() {
FileWriter writer;
try {
int i = 1;
writer = new FileWriter("D:\\text.txt");
writer.append("line"+ i++ + "\n");
writer.flush();
while (true)
{
writer.append("line"+ i++ + "\n");
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// start thread to read file
new Thread(new Runnable() {
#Override
public void run() {
try {
FileReader reader = new FileReader("D:\\text.txt");
BufferedReader br = new BufferedReader(reader);
String detail;
while ((detail =br.readLine()) != null)
{
System.out.println(detail);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
I did some experiment for it .
One eclipse run a program as writer .
public class Main {
private static Logger log = Logger.getLogger(Main.class);
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
PropertyConfigurator.configure("log4j.properties");
log.warn("Test test test ");
}
}
Another eclipse run the program as reader.
public class Main {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
StringBuffer intiLine = new StringBuffer("");
FileReader reader = new FileReader("D:\\logs\\notify-subscription.log");
BufferedReader br = new BufferedReader(reader);
String detail;
while ((detail =br.readLine()) != null)//debug and set breakpoint here
{
System.out.println(detail);
}
}
}
before I began to test them. The original log file content is empty.
I ran the reader program at first. the result of br.readLine() supposed to be null. But I set break point at the code line while ((detail =br.readLine()) != null) run, before it run , I ran the writer program. So the file contains test test test. and br.readLine() will not be null.
You are absolutely Correct .There will be a chance for Deadlock also if you keep creating threads for writing content to the file.Because if threads are keep on writing to the file there wont be any chance of exiting from loop it goes to infinite state
Whenever I run my code, the inv.txt file changes from having 25 lines of the character 1 to nothing, could someone tell me what I'm doing wrong?
PS the main class includes inventory.addItem();
public class inventory {
File inventory = new File("Resources/inv.txt");
File db = new File("Resources/db.txt");
FileWriter write;
StringBuilder writethis;
public void addItem(int item, int slot){
int i;
Scanner scan = null;
try {
scan = new Scanner(inventory);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
write = new FileWriter(inventory);
} catch (IOException e) {
e.printStackTrace();
}
for(i = 1; i < slot; i++)writethis.append(scan.nextLine());
System.out.println(writethis.toString());
}
}
Use write = new FileWriter(inventory, true);
It will append data to existing file. See the documentation on FileWriter Constructor for further details.