Writing to Text File [duplicate] - java

This question already has answers here:
BufferedWriter not writing everything to its output file
(8 answers)
Closed 8 years ago.
So I'm using this function to write to text file, but the text file always ends up empty after executing. Can anyone see what the error might be? I've been stuck on this for a while.
public static void writeTextFile(String fileName, String s) {
FileWriter output = null;
try {
output = new FileWriter(fileName);
BufferedWriter writer = new BufferedWriter(output);
writer.write(s);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
// Ignore issues during closing
}
}
}
}

Just change your to include writer.close(); as given below
try {
output = new FileWriter(fileName);
BufferedWriter writer = new BufferedWriter(output);
writer.write(s);
writer.close();
}
//remaining code
The reason your data not saved in the file because , The Data is saved only if you call writer.flush(); And calling the writer.flush() method is enough to just save data. But you need to close the BufferedWriter() like writer.close(); to avoid resource leak. The close() calls flush() method for you before closing the stream.

After writing your output you should make sure to flush and close the socket, specially because you are using a buffered output.
writer.write(s);
writer.flush();
writer.close();
If you don't do that, the BufferedWriter will wait for additional data, but there does come none and the program execution is stopped suddenly. Using flush here is optional, as when closing it the flush is implicit, but personally I call it everytime I need to be sure that something goes out. Just like when on the toilet ;)

When you use a Buffer to write something, you must close him when you re end
writer.close();

Without closing bufferwriter you cannot see output on text file
try to add this code
writer.close()

Related

Close a stream without assigning it to a variable [Java]

I'm reading a large file using the nio Files.lines method, and writing it to another file.
BufferedWriter writer = Files.newBufferedWriter(Path.of(outFile);
Files.lines(Path.of(inputFile))
.forEach(line -> {
try {
writer.write(line);
writer.newLine();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
writer.flush();
writer.close();
I want to close the writer and the stream (Files.lines) in a finally block.
I'm aware I'll have to surround this snippet in a try-catch-finally block, but how do I close the stream without assigning it to a variable?
Instead of doing lots of manual work, just use the following snippet (as you've been advised already in the comments):
Files.copy(Path.of(inputFile), Path.of(outFile)));
If you still want to do that manually for some reason, use try-with-resources. You will still assign the BufferedWriter to a variable, but there'll be no need to close it explicitly. Java will do that by itself:
try(BufferedWriter writer = Files.newBufferedWriter(Path.of(outFile));
Stream<String> lines = Files.lines(Path.of(inputFile))) {
// ... do something with your lines & writer here
}

Writing from Stream<String> to PrintWriter drops lines [duplicate]

For some reason my String is written partially by PrintWriter. As a result I am getting partial text in my file. Here's the method:
public void new_file_with_text(String text, String fname) {
File f = null;
try {
f = new File(fname);
f.createNewFile();
System.out.println(text);
PrintWriter out = new PrintWriter(f, "UTF-8");
out.print(text);
} catch (IOException e) {
e.printStackTrace();
}
}
Where I print text to a console, I can see that the data is all there, nothing is lost, but apparently part of text is lost when PrintWriter does its job... I am clueless..
You should always Writer#close your streams before you discard your opened streams. This will free some rather expensive system resources that your JVM must quire when opening a file on the file system. If you do not want to close your stream, you can use Writer#flush. This will make your changes visible on the file system without closing the stream. When closing the stream, all data is flushed implicitly.
Streams always buffer data in order to only write to the file system when there is enough data to be written. The stream flushes its data automatically every now and then when it in some way considers the data worth writing. Writing to the file system is an expensive operation (it costs time and system resources) and should therefore only be done if it really is necessary. Therefore, you need to flush your stream's cache manually, if you desire an immediate write.
In general, make sure that you always close streams since they use quite some system resources. Java has some mechanisms for closing streams on garbage collection but these mechanisms should only be seen as a last resort since streams can live for quite some time before they are actually garbage collected. Therefore, always use try {} finally {} to assure that streams get closed, even on exceptions after the opening of a stream. If you do not pay attention to this, you will end up with an IOException signaling that you have opened too many files.
You want to change your code like this:
public void new_file_with_text(String text, String fname) {
File f = null;
try {
f = new File(fname);
f.createNewFile();
System.out.println(text);
PrintWriter out = new PrintWriter(f, "UTF-8");
try {
out.print(text);
} finally {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Try to use out.flush(); right after the line out.print(text);
Here is a proper way to write in a file :
public void new_file_with_text(String text, String fname) {
try (FileWriter f = new FileWriter(fname)) {
f.write(text);
f.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
I tested you code. You forgot to close the PrintWriter object i.e out.close
try {
f = new File(fname);
f.createNewFile();
System.out.println(text);
PrintWriter out = new PrintWriter(f, "UTF-8");
out.print(text);
out.close(); // <--------------
} catch (IOException e) {
System.out.println(e);
}
You must always close your streams (which will also flush them), in a finally block, or using the Java 7 try-with-resources facility:
PrintWriter out = null;
try {
...
}
finally {
if (out != null) {
out.close();
}
}
or
try (PrintWriter out = new PrintWriter(...)) {
...
}
If you don't close your streams, not only won't everything be flushed to the file, but at some time, your OS will be out of available file descriptors.
You should close your file:
PrintWriter out = new PrintWriter(f, "UTF-8");
try
{
out.print(text);
}
finally
{
try
{
out.close();
}
catch(Throwable t)
{
t.printStackTrace();
}
}

How should I check if BufferedWriter is already closed?

In android, I am writing a file on clicking a button and on clicking next time, it saves the file and closes the buffered writer. But, I also want to implement functionality to close the buffered writer in onDestroy function. Before that I need to know if Bufferedwriter is already closed. How will I check if Buffered Writer is already closed?
In addition to that, does bufferedWriter.close() function set bufferedWriter to null?
Calling close method on already closed Writer has no impact.
Still, if you want to know if the Writer is closed, you can call writer.flush(), if it throws IOException then it means the Writer is already closed.
For your second question, closing a stream doesn't nullify the reference. You have to explicitly set it to null.
you can check if bufferredWriter not equal to null
if(bufferredWriter!=null)
{
bufferredWriter.close();
}
If you are using java7 or more then you need not to worry about closing the BufferredWriter
JDK 7 onwards you can make you of try with resource
for example
try(BufferredWriter bufferedWriter=new BufferredWriter())
{
//your code
}
catch(Exception e)
{
}
BufferedWriter vf = new BufferedWriter(new FileWriter("file"));
if (vf != null)
{
vf.close();
vf.close(); //won't cause any problem
}
you can close BufferedWriter as many times as you want if it is not null. So no need to check specifically if BufferedWriter is open or not.
Even better if you surround close statement in try/catch in case IOException occurs.
From javadocs
Closes the stream, flushing it first. Once the stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously closed stream has no effect.
And as explained by sidgate, closing a stream won't nullify the reference you have to assign it manually.
bufferedWriter.close() - Closes this writer. The contents of the buffer are flushed, the target writer is closed, and the buffer is released. Only the first invocation of close has any effect.
Refer this
Also, you can check like this
Define below 2 variables as instance variable
BufferedWriter bufferWriter;
boolean isOpen = false;
Then,
try {
if (!isOpen) {
bufferWriter = new BufferedWriter(new FileWriter(file, true));
bufferWriter.write(initialData);
isOpen = true;
}
bufferWriter.write(remainingData);
bufferWriter.flush();
Log.d(TAG, "written to file:" + file.getAbsolutePath());
} catch (IOException e) {
Log.v("IOException", e.toString());
}

What is referring to my file, preventing me from calling .delete() successfully?

I am making a game and have started to work on a class called SaveManager, so far I have had no problems except when it comes to deleting the game.
My problem is this, .delete() returns false the majority of times, without calling an exception.
If I make a loop (below) it does eventually delete, despite me not actually changing any variables or references and the game loop itself definitely doesn't deal with the files at all, so it isn't "releasing" the file itself at any point.
public void delete(File save)
{
while (save.exists() && !save.delete())
{
i++;
}
new infoBox("Times delete called: " + i, "delete method in saveManager");
So my question is: If the reference is not from one of my classes how do I find it and remove it, allowing me to remove the above loop, which basically hijacks the game until the file is gone.
Here is the code which does deal with the file, in case I am in fact doing something wrong (God Forbid!) I'm pretty sure this does "release" the save file in question...
private void save()
{
ObjectOutputStream OOS = null;
BufferedOutputStream BOS = null;
FileOutputStream FOS = null;
try
{
File saveFile = new File(saveDirectory + hub.world.saveName + ".dat");
OOS = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(saveFile, false)));
OOS.write... (List of Objects & Strings here)
OOS.flush();
OOS.close();
game.saved = true; //Used for warning message on exit
this.setSavesList();
}
catch (Exception e)
{
new errorWindow(e, "SaveFile, I/O error");
}
finally
{
try
{
FOS.flush();
FOS.close();
BOS.flush();
BOS.close();
OOS.flush();
OOS.close();
}
catch (IOException e)
{
hub.frame.errorWindow(e, "Problem closing streams");
}
}
}
One general thing to check while dealing with files is if you're closing any opened streams before attempting to delete it.
You can't delete a file unless the stream opened is closed.
Take a look at this.
You are creating three streams, and only closing the top-most one (OOS).
You should close each stream manually. I think that will fix your problem.
Also, it's often considered good practice to put the close() in a finally block, so it definitely happens.
FileOutputStream fos = new FileOutputStream(fileName);
try
{
BufferedOutputStream bos = new BufferedOutputStream(fos);
OOS = new ObjectOutputStream(bos);
OOS.write... (List of Objects & Strings here)
OOS.flush();
OOS.close();
bos.flush();
bos.close();
game.saved = true; //Used for warning message on exit
this.setSavesList();
} catch (IOException ioe)
{
}
finally
{
fos.close();
}
Otherwise, you might flush the object output stream, and the data just gets stuck in the buffered output stream, and never gets written to the file output stream.
Here's a food for thought...from the code above, you have used a try-catch block...my guess is that one of the above operations is throwing an exception because of which the out.close() operation is getting skipped...why not add a "finally" block and close the stream there...it would definitely help you save the trouble.
Are you sure your file is actually being created? In the code snippet above you have while(!save.delete()) but later on you seem to refer to it as saveFile, these may be two different files! I would first check to see if the file even exists on the disk by doing an
if(!saveFile.exists()) {
do something here
}
if it doesnt exist, a delete will just return false, you cannot delete a file that does not exist.
If you are checking the result of delete you also need to check whether the files exists. Obviously if there is not file or it has already been deleted, delete() will return false. ;)

When should I close() a BufferedWriter?

I'm appending a line to a textfile each time a button is pressed. Currently I'm doing this each time the button is pressed:
...
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));
if (fileIsNew == true)
bw.write(firstLine);
bw.write(string);
bw.close();
Log.v("file", "written to file:" + f.getAbsolutePath());
} catch (IOException e) {
Log.v("IOException", e.toString());
}
...
I don't think it's really a good idea to close the bufferedwriter after each line as the purpose of a bufferedWriter is to buffer the output, right?
So when should I call bw.close() ?
And should I create the new BufferedWriter in some kind of init()?
I think it's inefficient to create a new BufferedWriter each time the button is pressed.
You can declare it as a member field, create it upon first press on the button, by setting a flag, and keep it open.
On each press, call write() and then flush() (to avoid content loss).
BufferedWriter bw;
boolean isOpen = false;
// ..
try {
if (!isOpen) {
bw = new BufferedWriter(new FileWriter(logFile, true));
bw.write(firstLine);
isOpen = true;
}
bw.write(string);
bw.flush();
Log.v("file", "written to file:" + logFile.getAbsolutePath());
} catch (IOException e) {
Log.v("IOException", e.toString());
}
In this article you can find that, in a good programming style:
The short answer is that you should create a FileWriter instance with the append flag set to true, like this:
BufferedWriter bw = new BufferedWriter(new FileWriter("checkbook.dat", true));
Have fun
You should always close the buffered reader if you are not going to use it again, which is the case here. Otherwise, you leave to the GC to decide when to collect the object, and the resource will be disposed at that time.
So the short answer is: ALWAYS!
You basically answered the question yourself, the whole purpose of it it IO buffering. Usually you'd open it once, could be in init or whenever it is first needed, you flush and close it when you're done writing all the data. Note however, that unless you explicitly call flush(), the content may be written not at the exact moment you call write() to it but buffered for later output.

Categories