I've an app that is writing data to a file. The first time I run it, it goes grand and writes 1000s of values to the file. Then I close the app using this code
finish();
System.exit(0);
Which happens when I hit the stop button.
When I run it again after stopping, say in a few minutes, it only writes a few values to a new file, over the same time frame.
Here is the code I use to write to the file:
public void write(String message) {
try {
if (out == null) {
FileWriter datawriter = new FileWriter(file, true);
out = new BufferedWriter(datawriter);
//out.write("X Value, Y Value, Z Value \n");
}
if (file.exists()) {
out.append(message);
out.flush();
}
Any insight into why this is happening would be much appreciated.
Thanks
On finishing do out.close(). It probably is a system deteriorating.
Do not call
System.exit(0);
Read this post to know why.
Also, you shouldn't need to call flush(), but just close() when you're done, before your call to finish().
Try with this code:
public void write(String message) {
try {
if (out == null) {
FileWriter datawriter = new FileWriter(file, true);
out = new BufferedWriter(datawriter);
}
out.append(message);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
Related
I am writing a file into a directory. There might be the chance that the directory becomes unreachable.
What I want to do is..
As the code is writing to the file, if the directory becomes unreachable or a file not found exception is thrown I want it to keep checking if the directory exists and continue where I left off after the directory exists again.
After some time if the directory does not come back up then I would shut the program down.
My problem is that when a file not found exception is thrown the program just shuts down all together. Here is my code:
public class BusStopsProcessor implements Runnable
{
private BlockingQueue<Bus<buses>> busQueue;
private Bus<buses> BusObject;
public BusStopsProcessor(BlockingQueue<Bus<buses>> busQueue)
{
this.busQueue = busQueue;
}
#Override
public void run()
{
try
{
String path = "C:\\Users\\Me\\Documents\\";
File file = new File(path + "busStopsFile.txt");
FileWriter fw = new FileWriter(file, true);
CSVWriter writer = new CSVWriter(fw, '|', CSVWriter.NO_QUOTE_CHARACTER);
while(true)
{
BusObject = busQueue.take();
//each bus object should have a bus date if it does not then it is a
//poison bus object.
if(BusObject.getBusDate() != null)
{
createBusFile(BusObject, writer);
else
{
try
{
//Finished processing bus stops so close writer.
writer.close();
fw.close();
break;
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
e.printStackTrace();
}
catch (FileNotFoundException e)
{
//If a FILENOTFOUND exception is thrown here I want
//my code to be able to pick up where I left off
e.printStackTrace();
logger.warn(e.getMessage());
}
catch (IOException e)
{
e.printStackTrace();
}
}
Here is the method that I want to keep checking if the directory exists. If the file is being written into and all of a sudden the directory goes down. I dont want to repeat the same information in the file I want it to continue to write from where it left off but I just cant figure out how to do that. thank you.
private void createBusFile(Bus<buses> aBusObject, CSVWriter writer) throws InterruptedException
{
//Get bus information here
for(Bus<buses> busStop : aBusObject.getBusStops())
{
busNumber = busStop.getBusNumber();
busArrivalTime = busStop.getBusArrivalTime();
busStop = busStop.getBusStop();
String[] busFields = {busNumber, busDate, busStop};
//If a file not found exception is thrown here I want it to keep checking if the directory exists. And pick up from where I left off
writer.writeNext(busFields);
}
}
}
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
}
I have one of the biggest problem in my program. I've created Save button, but it saves if the .txt file is new (Then that button does "SaveAs" function). But when I open file, then type something and trying to save and it's not saving :S. Can anyone help me?
Here's the code:
fileSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(currentFile == null) {
int saveResult = fileSelect.showSaveDialog(null);
if(saveResult == fileSelect.APPROVE_OPTION) {
saveFile(fileSelect.getSelectedFile(), field.getText());
} else {
saveFile(currentFile, field.getText());
}
}
}
});
public void saveFile(File file, String contents) {
BufferedWriter writer = null;
String filePath = file.getPath();
if(!filePath.endsWith(".txt")) {
filePath += ".txt";
}
try {
writer = new BufferedWriter(new FileWriter(filePath));
writer.write(contents);
writer.close();
field.setText(contents);
setTitle("Editex - " + filePath);
currentFile = file;
} catch (Exception e) {
}
}
You aren't handling when currentFile != null, which is what I am assuming is the case when you are trying to save a file that already has a Filename.
Do something like this:
if(currentFile == null) {
// Handle if new file
} else {
// Handle an existing file
}
Move
saveFile(currentFile, field.getText());
into the else part of the above if else.
At the moment you have it within the if(currentFile == null), and this isn't the correct place as you are calling saveFile(null, field.getText()) here.
Also
catch(Exception e) {
}
is bad, never swallow an exception and do nothing with it, you will never know if an exception happens or not, just nothing will happen.
I use the following method to playback a recorded sound, it works fine, but why it only plays once, the second time I click the play button, it does nothing, how to reset the data ?
// Write data to the OutputChannel.
public class Playback implements Runnable
{
SourceDataLine line;
Thread thread;
public void start()
{
errStr=null;
thread=new Thread(this);
thread.setName("Playback");
thread.start();
}
public void stop() { thread=null; }
private void shutDown(String message)
{
if ((errStr=message)!=null)
{
System.err.println(errStr);
samplingGraph.repaint();
}
if (thread!=null)
{
thread=null;
samplingGraph.stop();
if (Java_Sound.Running_In_All_Permissions_Mode) captB.setEnabled(true);
pausB.setEnabled(false);
playB.setText("Play");
}
}
public void run()
{
AudioFormat format=formatControls.getFormat(); // get an AudioInputStream of the desired format for playback
AudioInputStream playbackInputStream=AudioSystem.getAudioInputStream(format,audioInputStream);
if (playbackInputStream==null)
{
shutDown("Unable to convert stream of format "+audioInputStream+" to format "+format);
return;
}
SourceDataLine.Info info=new DataLine.Info(SourceDataLine.class,format); // define the required attributes for our line,and make sure a compatible line is supported.
if (AudioSystem.isLineSupported(info))
{
try // get and open the source data line for playback.
{
line=(SourceDataLine)AudioSystem.getLine(info);
line.open(format,bufSize);
}
catch (LineUnavailableException ex)
{
shutDown("Unable to open the line: "+ex);
return;
}
int frameSizeInBytes=format.getFrameSize(); // play back the captured audio data
int bufferLengthInFrames=line.getBufferSize()/8;
int bufferLengthInBytes=bufferLengthInFrames*frameSizeInBytes;
byte[] data=new byte[bufferLengthInBytes];
int numBytesRead=0;
line.start(); // start the source data line
while (thread!=null)
{
try
{
if ((numBytesRead=playbackInputStream.read(data))==-1) break;
int numBytesRemaining=numBytesRead;
while (numBytesRemaining>0) { numBytesRemaining-=line.write(data,0,numBytesRemaining); }
}
catch (Exception e)
{
shutDown("Error during playback: "+e);
break;
}
}
}
if (thread!=null) line.drain(); // we reached the end of the stream. Let the data play out,then stop and close the line.
line.stop();
line.close();
line=null;
shutDown(null);
}
}
After my test, I found this line is causing the problem
"if ((numBytesRead=playbackInputStream.read(data))==-1) break;"
The first time I played back, there were data, it worked fine, but the second time, it broke. Why ? How to fix it ?
Never worked with java audio, but since you are using stream, you need to either reset the stream if that option is available, or need to create new stream every time you read it.
I figured it out, add the following line after "shutDown(null)"
if (file==null)
try { audioInputStream.reset(); }
catch (Exception e) { e.printStackTrace(); }
Now it works perfect.