Write to External File without ending the program - java

I have a program that is only meant to be terminated by pressing Ctrl + C. In this program I write to an external file using:
File logFile = new File("output.txt");
PrintWriter log_file_writer = new PrintWriter(logFile);
log_file_writer.println("TEXT");
However because I don't know when the program will be terminated, I can't close the file using:
log_file_writer.close();
I think this is resulting in no text appearing in the output file.
Would anyone have a solution for this?
Thank you for your help.

log_file_writer.flush();
will push the content to disk

As the javadoc says:
PrintWriter(File file) Creates a new PrintWriter, without automatic line flushing, with the specified file.
Therefore, you need to flush the data you want to print that is actually buffered:
log_file_writer.flush();

You did not flush the content, I always use the autoFlush argument, but it is not available with File:
PrintWriter log_file_writer = new PrintWriter(new FileOutputStream("output.txt"),true);
but you can also use log_file_writer.flush(); after each write.

Related

PrintWriter erases file of contents before the close() function executed

I am trying to write contents of my parsed HTML with PrintWriter so I can convert HTML to the other formats. But PrintWriter erases file of contents before the close() function executedçI can use other file writing techniques but I am wondering why PrintWriter behave like this.
for (Element element : elements) {
if (element.tagName() == "a") {
PrintWriter writer2 = new PrintWriter("contenthtml.html", "UTF-8");
writer2.print(a.ExtractHTMLByIDandDomain(Domain + element.attr("href"), Content_HTML_ID));
Process proc = Runtime.getRuntime().exec("pandoc -f html -t asciidoc contenthtml.html >> contentasciidoc.adoc");
//Thread.sleep(5000); //I have tried wait but it didn't work
writer2.flush();
writer2.close();
}
There are a few problems with your code:
You cannot compare strings with '==', as '==' compares references. If element.getTagName() is "a", whether that if on line 2 of your paste actually fires depends on the situation, but it probably wont.
A PrintWriter is a resource. Resources need to be closed; if you do not close them, the resource remains open indefinitely, and this is called a resource leak. Use the Automatic Resource Management construct for a convenient way to do so.
You create the printwriter, tell the printwriter to write some data, you do not flush or close the resource, you then exec another process, and finally after that process completes, you flush/close. Which means, the file is empty, as printwriter buffers. You should write your file and then close your resource, and only then call the external process; both you and the process you launch having the same file open at the same time is confusing and problematic, and in this case, unneccessary, so, don't.
Runtime.getRuntime().exec() is NOT bash and NOT a command line prompt. The concept of redirecting via >> someFile.txt is a bashism/command-promptism. Runtime has no idea what you're talking about and will just pass it along as an argument to the launched process. Invoke bash if you need bash's redirection features or write the redirection in java by reading the outputstream of the process and appending it to the file yourself.
Applying all 4 fixes:
create a file named 'run.sh' containing:
#!/bin/sh
pandoc -f html -t asciidoc contenthtml.html >> contentasciidoc.asciidoc
and update your java code:
for (Element element : elements) {
if ("a".equalsIgnoreCase(element.tagName()) {
try (PrintWriter writer2 = new PrintWriter("contenthtml.html", "UTF-8")) {
writer2.print(a.ExtractHTMLByIDandDomain(Domain + element.attr("href"), Content_HTML_ID));
}
}
Process proc = Runtime.getRuntime().exec("/usr/bin/bash run.sh");
}
There is no guarantee that PrintWriter will write to the file until you call flush()
It might work if you move flush() to before exec()
First: Please read an try to understand the answer rzwitserloot wrote because it contains some valid constructive criticism.
To answer your question why PrintWriter deletes already existing file contents: It's designed to do so. If you look in the documentation for PrintWriter which you can find here: https://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html#PrintWriter(java.io.File,%20java.lang.String)
The part about the File Parameter:
file - The file to use as the destination of this writer.
If the file exists then it will be truncated to zero size; otherwise, a new file will be created. The output will be written to the file and is buffered.

How can I deleting the content of a file without deleting it self?

I want to clear the content of a file witch have a specific extension file.tctl, i don't want to change any thing about the file neither deleting it. The file is generated from a specific model checker so that i have just to delete the content and write my own. I tried to print an empty string like that:
PrintWriter writer = new PrintWriter(file.tctl);
writer.print("");
writer.close();
but the file doesn't work any more. So if there's another method to clear the content of the file.
Just remove the print altogether from your code. You've already truncated the file with the new FileOutputStream/PrintWriter/ whatever you use to open it. No I/O or truncate() necessary. Don't use append mode.
Most easy way I guess
new RandomAccessFile("filename.ext", "rw").setLength(0);
Call your write() method like this:
.write((new String()).getBytes());
This will make your file empty. If that doesn't works, try with this:
FileOutputStream erasor = new FileOutputStream("filename.ext");
erasor.write((new String()).toByteArray());
erasor.close();
Or just try to overwrite the file
//open file in override mode
FileOutputStream out = new FileOutputStream("filename.ext");
//now anything that we write here will remove the old one so just write space ("") here
You have to use a FileOutputStream and then you have the truncate() method:
File f = new File("path-of-the-file.here");
FileChannel channel = new FileOutputStream(f, true).getChannel();
channel.truncate(0);
channel.close();

Clear contents of a file in Java using RandomAccessFile

I am trying to clear the contents of a file I made in java. The file is created by a PrintWriter call. I read here that one can use RandomAccessFile to do so, and read somewhere else that this is in fact better to use than calling a new PrintWriter and immediately closing it to overwrite the file with a blank one.
However, using the RandomAccessFile is not working, and I don't understand why. Here is the basic outline of my code.
PrintWriter writer = new PrintWriter("temp","UTF-8");
while (condition) {
writer.println("Example text");
if (clearCondition) {
new RandomAccessFile("temp","rw").setLength(0);
// Although the solution in the link above did not include ',"rw"'
// My compiler would not accept without a second parameter
writer.println("Text to be written onto the first line of temp file");
}
}
writer.close();
Running the equivalent of the above code is giving my temp file the contents:(Lets imagine that the program looped twice before clearCondition was met)
Example Text
Example Text
Text to be written onto the first line of temp file
NOTE: writer needs to be able to write "Example Text" to the file again after the file is cleared. The clearCondition does not mean that the while loop gets broken.
You want to either flush the PrintWriter to make sure the changes in its buffer are written out first, before you set the RandomAccessFile's length to 0, or close it and re-open a new PrintWriter to write the last line (Text to be written...). Preferably the former:
if (clearCondition) {
writer.flush();
new RandomAccessFile("temp","rw").setLength(0);
You'll be lucky if opening the file twice at the same time works. It isn't specified to work by Java.
What you should do is close the PrintWriter and open a new one without the 'append' parameter, or with 'append' set to 'false'.

Writing from console to text file, file data not saved

I am trying to save the content of the java console into a text file but each time I close the program the text file goes blank and rewrites to it. i.e. if I write to a file today, close the program and come back and run it again tomorrow, it has remembered the information written to it.
You want to open the OutputStream in append mode. Demo code:
PrintWriter out = new PrintWriter(
new FileOutputStream(new File(filename), true));
What you experience is the normal behavior when you write a stream to a file, and this is not specific to the Java API.

Using PrintWriter with files

In case I have the following code:
private PrintWriter m_Writer;
m_Writer = new PrintWriter(new FileWriter(k_LoginHistoryFile));
I am writing to a local file on server which name is k_LoginHistoryFile.
Now, as my program runs it doing writings to this file so how can I delete all the file content between each writes?
I think it is important as I don't want to write to a file which will eventually have current updated information on its beginning + not up to date info at its end.
Thanks in advance
This expression:
new FileWriter(k_LoginHistoryFile)
will truncate your file if it exists. It won't just overwrite the start of the file. It's not clear how often this code is executing, but each time it does execute, you'll start a new file (and effectively delete the old contents).
I think it is important as I don't want to write to a file which will eventually have current updated information on its beginning + not up to date info at its end.
If you want to keep a running output file (and you can't keep the file open), consider this constructor: FileWriter(String, boolean)
If the boolean is true, your updated information will be at the end of the file.

Categories

Resources