i noticed in a java program the below line used to open a file and process it
BufferedReader inp = new BufferedReader(new FileReader(inputFile));
In the javaprogram the inp is not closed before exiting the program the below line is missing
if (inp != null)
try {
inp.close();
} catch (IOException logOrIgnore) {}
The program has exits in a lot of place but they had not closed the file. Do i need to put this line everywhere? If i dont close the file when the program exits will it be a issue.
Does the garbage collector closes the file?
You should use try/finally:
Reader inp = new BufferedReader(new FileReader(inputFile));
try {
// Do stuff with "inp"
} finally {
IOUtils.closeQuietly(inp);
}
IOUtils is from Apache Commons IO. Its closeQuietly method is like your code snippet above: it calls close, and ignores any exceptions thrown.
The garbage collector does not close the file. If you know your program will not be long running or open many files, you can get away without closing the file. But otherwise you need to close it manually.
It sounds like you're using the BufferedReader without returning to the context in which it was declared (possibly an instance variable?). In that instance, you must close it manually upon each possible exit from your application. You cannot rely on the garbage collector to do this for you.
Related
I have a Java program that reads some text from a file, line by line, and writes new text to an output file. But not all the text I write to my BufferedWriter appears in the output file after the program has finished. Why is that?
The details: the program takes a CSV text document and converts it into SQL commands to insert the data into a table. The text file has more than 10000 lines which look similar to following:
2007,10,9,1,1,1006134,19423882
The program seems to work fine except it just stops in the file randomly half way through creating a new SQL statement having printed it into the SQL file. It looks something like:
insert into nyccrash values (2007, 1, 2, 1, 4, 1033092, 259916);
insert into nyccrash values (2007, 1, 1, 1, 1, 1020246, 197687);
insert into nyccrash values (2007, 10, 9, 1
This happens after about 10000 lines but several hundred lines before the end of the file. Where the break happens is between a 1 and a ,. However, the characters doesn't seem important because if I change the 1 to a 42 the last thing written to the new file is 4, which is cutting off the 2 from that integer. So it seems like the reader or writer must just be dying after writing/reading a certain amount.
My Java code is as follows:
import java.io.*;
public class InsertCrashData
{
public static void main (String args[])
{
try
{
//Open the input file.
FileReader istream = new FileReader("nyccrash.txt");
BufferedReader in = new BufferedReader(istream);
//Open the output file.
FileWriter ostream = new FileWriter("nyccrash.sql");
BufferedWriter out = new BufferedWriter(ostream);
String line, sqlstr;
sqlstr = "CREATE TABLE nyccrash (crash_year integer, accident_type integer, collision_type integer, weather_condition integer, light_condition integer, x_coordinate integer, y_coordinate integer);\n\n";
out.write(sqlstr);
while((line = in.readLine())!= null)
{
String[] esa = line.split(",");
sqlstr = "insert into nyccrash values ("+esa[0]+", "+esa[1]+", "+esa[2]+", "+esa[3]+", "+esa[4]+", "+esa[5]+", "+esa[6]+");\n";
out.write(sqlstr);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
You need to close your OutputStream which will flush the remainder of your data:
out.close();
The default buffer size for BufferedWriter is 8192 characters, large enough to easily hold hundreds of lines of unwritten data.
You must close() your BufferedWriter. You must close() your BufferedWriter because it IS-A Writer and thus implements AutoCloseable, which means (emphasis added) it is
A resource that must be closed when it is no longer needed.
Some people say you must first call flush() for your BufferedWriter before calling close(). They are wrong. The documentation for BufferedWriter.close() notes that it "Closes the stream, flushing it first" (emphasis added).
The documented semantics of flushing (flush()) are
Flushes this stream by writing any buffered output to the underlying stream
So, you must close, and close will flush any buffered output.
Your output file does not include all the text you wrote to your BufferedWriter because it stored some of that text in a buffer. The BufferedWriter never emptied that buffer, passing it through to the file, because you never told it to do so.
Since Java 7, the best way to ensure an AutoCloseable resource, such as a BufferedWriter, is closed when it is not longer need is to use automatic resource management (ARM), also known as try-with-resources:
try (BufferedWriter out = new BufferedWriter(new FileWriter(file))) {
// writes to out here
} catch (IOException ex) {
// handle ex
}
You must also close your BufferedReader when it is no longer need, so you should have nested try-with-resources blocks:
try (BufferedReader in = new BufferedReader(new FileReader("nyccrash.txt")) {
try (BufferedWriter out = new BufferedWriter(new FileWriter("nyccrash.sql"))) {
// your reading and writing code here
}
} catch (IOException ex) {
// handle ex
}
Do not be tempted (as other answers here suggest) just to call close() at the end of your method, when your code has "finished" using the writer. That will not work if your writing code throws an exception, and in particular if it throws an IOException.
A resource that must be closed when it is no longer needed.
finally {
out.close();//this would resolve the issue
}
Some things to consider:
BufferedWriter.close() flushes the buffer to the underlying stream, so if you forget to flush() and don't close, your file may not have all the text you wrote to it.
BufferedWriter.close() also closes the wrapped Writer. When that's a FileWriter, this will ultimately close a FileOutputStream and tell the OS that you're done writing to the file.
The garbage collector will automatically call close(), not on the BufferedWriter or the wrapped FileWriter, but on the FileOuputStream. So the OS will be happy, but you have to wait for the GC.
However, you always want to release OS resources as soon as you no longer need them. This goes for open files, database connections, print queues ... anything. Trust me on this one.
BufferedWriter.close() does clear up the internal character buffer, so that memory will be available for garbage collection, even while the BufferedWriter itself remains in scope.
So, Always close your resources (not just files) when you're done with them.
If you really want a peek under the covers, most of the Java API's source is available. BufferedWriter is here.
Your code does not appear to be closing the writer after you've finished writing to it. Add an out.close() (preferably in a finally block) and it should work properly.
you dint close your BufferedWriter.close it inside a finally block
finally {
out.close();//this would resolve the issue
}
Always close your resources (not just files) when you're done with them.
finally {
out.close();//this would resolve the issue
}
There might be situations when you want to flush the buffer without closing the file. In these situations you can use the flush-method.
Since you're using BufferedWriter you can also flush the buffer when appropriate:
out.flush()
This will write the rest of the buffer to the actual file. Close-method also flushes the buffer and closes the file.
out.close()
There might be situations when you want to flush the buffer without closing the file. In these situations you can use the flush-method.
You can also use BuffredWriter's newline-method instead of adding \n to the end of the line. Newline-method uses system specific line separator so your code works on different platforms.
out.newLine()
According to documentation it is no use calling flush() method. If you intent to use FileWriter then flush() would help you out.
Basically in this case, you just need to close, BufferedWriter.close() only. This will flush the remainder of your data.
create finally block and put the close method inside so that it will put all data without missing.
finally {
out.close();
}
Goodmorning guys,
I'm trying to develop an Eclipse Plugin that run an external program with ProcessBulder.
During the exectution, I try to write the output on disk, but the plugin doesn't write anything until I close the execution of Eclipse Application.
public void run()
{
ProcessBuilder pb = new ProcessBuilder("NuSMV.exe","-int");
Process process = null;
try {
process = pb.start();
} catch (IOException e) {
e.printStackTrace();
}
OutputStream out = process.getOutputStream();
// Write commands
PrintWriter commands = new PrintWriter(out);
commands.println("reset");
commands.println("set default_trace_plugin 4");
commands.println("read_model -i C:\\temp/ascensore.smv");
commands.println("go");
commands.println("check_ctlspec");
commands.println("show_traces -o C:\\temp/showtraces.xml");
commands.close();
process.getOutputStream().close();
}
Showtraces.xml is written after the end of eclipse. How Can I have the output before this closing?
First flush the printwriter then close it.
ie
commands.flush();
Refer.
http://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html#flush--
I am not sure it will help but try to change this:
commands.close();
process.getOutputStream().close();
To this:
commands.flush();
commands.close();
out.flush();
out.close();
I've already tried to use commands.flush() before call the close() method, but this don't change anything.
Instead, if I write more than one file, as an example file-1.xml, file-2.xml, file-3.xml, the files numer one and two was written before I closing the application and the file number three was written only after closing.
Use another constructor to have the autoflush mode set (see Javadoc).
PrintWriter commands = new PrintWriter(out, true);
Changing this allows you to keep your code with minimal change.
Every call to println, printf and format flushes the buffer automatically, fixing your issues.
This question already has answers here:
Why does a Try/Catch block create new variable scope?
(5 answers)
Closed 8 years ago.
I have the following code, which works nicely in my class reading a file line by line.
try { FileInputStream in = new FileInputStream(filename);
BufferedReader reader=new BufferedReader(new InputStreamReader(in));
String line;
while((line=reader.readLine())!=null){
// read the file
}
}
catch (Exception e) {
System.out.println(e);
}
But if I try to add the command close, for after the file was finished reading, then I got the error:
in.close();
Error:(131, 9) java: cannot find symbol
symbol: variable in
location: class ReadFile
I searched about cleaning objects after use and the need to close files before your program ends. And found several posts on this for Java, but many are very contradictory. The point is that in the end I just get very confused.
Am I wrong, or Java programming is a little bit fuzzy and messy? I mean, there is apparently no real use of destructor, the use of finalize is very questionable, and the use of close is also suggested as unnecessary. Some of the posts on these issues are contradictory and non-conclusive.
So, how to proceed here? In the case I really need to close the file, how to get rid of this error message? Is it really dispensable and unnecessary to close files? What about cleaning up class instances for the the program finishes?
You are getting the error because you have defined variable in inside the try block, so it is not visible in catch/finally/or anywhere outside that try. Move the declaration outside try:
Change this
try { FileInputStream in = new FileInputStream(filename);
to
FileInputStream in = null;
try { in = new FileInputStream(filename);
you may be closing in.close() out side try block so obviously you will get error because in is defined in try block which is local.
Better to use try with resource so you need not to manually close file stream
Ideally you must call the close() method inside the finally block, after the null check.
And for that you need to declare the variable in outside the try block.
Calling the close() method in finally block ensures that it is called irrespective of whether an Exception is thrown or not by the code in try block.
EDIT : This is when you are using Java 6 or earlier version. For Java 7 and higher you could use try with resource as suggested by #JqueryLearner
i was doing a sample about reading files. I put a txt file into project folder and wrote this code but I got the exception FileNotFound and also when I try to close dataInputStream I am getting compile error(commented out line). I think I messed up everything
String str=null;
try {
FileInputStream fileInputStream=new FileInputStream("myfile.txt");
DataInputStream dataInputStream=new DataInputStream(fileInputStream);
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(dataInputStream));
str=bufferedReader.readLine();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(str);
//dataInputStream.close();
Java is really nitpicky about relative paths, so `"myfile.txt" should probably live wherever your project is being built.
As for closing the dataInputStream, it is not in scope. Declare it outside of your try block. In any case, I'd suggest placing the actual close() call in a finally block to make sure it is always done (if the reference isn't null).
I agree with Guillermo
myfile.txt needs to be in your class path.
If you run this code in command line, it should be located in the same folder as this code executes, or same package.
as for the datainput stream it is out of scope
bufferedReader.close() must use in the end of where you close this operation..
I use the following code to write some data to files:
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(file));
writer.write(...);
writer.flush();
}
finally {
if (writer != null)
writer.close();
}
After invoking the method multiple times I got a FileNotFoundException because too many files are open.
Obviously java does not close the file handles when I close the writer stream. Closing the FileWriter separately does not help.
Is there sth. I can do to force java to close the files?
Your code looks fine. It could be another part of your application which is leaking file handles.
You can monitor file handles using lsof on Linux or pfiles on Solaris. On Windows, you can use ProcessExplorer.
No, Java does close the file handles when you close the writer. Its actually built using Decorator pattern. Hence, it must be something else. Show the stack trace.
See this thread about writing to files, good tips there.. pay attention to the finally block in Anons reply.
BufferedWriter closes the underlying stream. Probably, this a multithreading issue. You can keep an instance of FileOutputStream and close it. Something like:
java.io.FileOutputStream out = new java.io.FileOutputStream(file);
try {
// make buffered writer, etc.
} finally {
out.close();
}