I have written a small piece of code for printing:
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(FileDescriptor.out), "ASCII"), 512);
out.write(msg + '\n');
out.flush();
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(
"Test failed ",
e);
} catch (IOException e) {
throw new IllegalStateException(
"Test failed", e);
} finally {
if (out != null) {
out = null;
}
}
Flushing of obj is done in the try block only. So is it a good way to do it or should I flush the object in the finally block?
Use modern syntax if you can and don't worry about all that. Closing will automatically flush it, so just use the try-with-resources syntax. This code is much shorter and more readable:
try(BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(FileDescriptor.out), "ASCII"), 512)) {
out.write(msg + '\n');
} catch (UnsupportedEncodingException | IOException e) {
logger.info("Test failed due to exception.");
throw new IllegalStateException("Test failed", e);
}
See more about try-with-resources if you are unfamiliar with the syntax.
The answer is "it depends." When do you want the text to be available for reading? If you don't need any of the text to be available for reading (i.e. no other process is actively waiting for on the stream as input), then you don't need to flush the stream until you are done with it (in the finally block). But you don't even need to explicitly do this since closing the stream automatically flushes it.
If another process is waiting on the stream, then you should flush whenever you want that output available to the other process. Flushing too often negates the benefits of buffering, however.
As others have noted, flushing and closing a stream can also throw an exception, so these actions should also be in their own try/catch block (a static utility method can be helpful for reducing the amount of boilerplate code when working with streams).
Related
I have a program that does a lot of processing with loops and writes strings to a file at many different points. I'm not sure about the overall design for how best to do this. I won't need to read from the file at any point during running, though will want to view it afterwards.
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
At the moment the skeleton looks like:
try (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer)) {
} catch (IOException e) {
//catch IO error
}
for (//main loop){
bw.write(string);
for (//several sub loops){
bw.write(//more strings);
}
for (//several sub loops){
bw.write(//more strings);
}
}
bw.write(//final string);
try {
bw.close();
} catch (IOException ex) {
//catch IO error
}
Does this look reasonable or is there a better way? Thanks very much in advance for the help.
Edit - thanks to you all for the help, totally answered my questions.
Firstly, is a BufferedWriter with FileWriter a reasonable way of doing this?
Yes, it should be the most convenient way to do this.
Secondly, presumably I don't want to be opening and closing this every time I want to write something (several times per second).
You really shouldn't. But you would actually overwrite your progress this way everytime you open the file anyway. That's because you didn't tell the FileWriter to append to an existing file (via new FileWriter("filename.txt", true);.
But if I use try with resources then I'd have to put practically the entire program inside that try, is this normal?
I don't see a problem with that. You can (and should) always move your logic into own methods or classes, which may return the Strings to write. This way you get the actual business logic separated from the technical file writing logic and structure your code, making it easier to understand.
You could also just write into a giant big String and then write that String in the try-with-resources block. But that has it's limits with really big files and may not be the best choice sometimes.
It is totally OK to put the whole Code into a try-catch routine. Whenever you have issues to write into the file it will just catch it and does not give you an error. However, I would recommend you to try this structure with just one try-catch routine.
try { (FileWriter writer = new FileWriter("filename.txt");
BufferedWriter bw = new BufferedWriter(writer))
for (/*main loop*/){
bw.write(string);
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
for (/*several sub loops*/){
bw.write(/*more strings*/);
}
}
bw.write(/*final string*/);
bw.close();
} catch (IOException e) {
System.out.println("error");
}
PS: If you comment something between some code use this:/* comment */ instead of this:// because it will comment out the whole line.
But if I use try with resources then I'd have to put practically the
entire program inside that try, is this normal?
Thats just how try-catch-with-resources work - it closes resources on exiting try block. If that is bothering you, don't use that construct and you manage writer yourself.
Above skeleton will not work as first try will open and close your writers;
Here is an alternate that does finer exception handling. In many cases, this is preferred. Having a catch block handle too many exceptions gets to be very confusing: Control flow is obscured, and diagnosing errors can be a lot harder.
Having a file open through the entire time a program is running is very usual. This is often the case for log files. If you know your program will be running for a long time, and if you suspect there will be long delays between output to a single file, you could open and close the file for each batch of close in time operations. But you would have to have a clear idea of the pattern of activity to do this, as you will want to match the open time of the file with expected close-in-time batches of writes. You should very much avoid high frequency open and close operations. That has all sorts of unwanted extra overhead.
package my.tests;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.function.Consumer;
public class WriterTest {
public static final String TARGET_NAME = "filename.txt";
public void performMainLoop() {
performWrites( this::mainLoop, TARGET_NAME );
}
public void performWrites( Consumer<Writer> writeActor, String targetName ) {
FileWriter fileWriter;
try {
fileWriter = new FileWriter(targetName);
} catch ( IOException e ) {
System.out.println("Open failure: " + e.getMessage());
e.printStackTrace();
return;
}
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(fileWriter);
writeActor.accept(bufferedWriter);
} finally {
if ( bufferedWriter != null ) {
try {
bufferedWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
} else {
try {
fileWriter.close();
} catch ( IOException e ) {
System.out.println("Unexpected close failure: " + e.getMessage());
e.printStackTrace();
}
}
}
}
public void mainLoop(Writer writer) {
for ( int loopNo = 0; loopNo < 10; loopNo++ ) {
try {
writer.write("Loop [ " + Integer.toString(loopNo) + " ]\n");
} catch ( IOException e ) {
System.out.println("Unexpected write failure: " + e.getMessage());
e.printStackTrace();
return;
}
}
}
}
Will this method cause a memory leak when it throws an exception?
public static void warnUser(String name) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(dir + "warnings.txt", true));
writer.newLine();
writer.write(name);
writer.close();
} catch (Exception e) {
System.out.println(e.getMessage());
System.err.println("error giving warning to: " + name);
}
}
Is this better?
public static void warnUser(String name) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(dir + "warnings.txt", true))) {
writer.newLine();
writer.write(name);
} catch (Exception e) {
System.out.println(e.getMessage());
System.err.println("error giving warning to: " + name);
}
}
A memory leak? No, once execution leaves this method, be it through return or throwing an exception, the BufferedWriter object will no longer be reachable, and becomes eligible for garbage collection.
However, as you are not invoking the close method when an exception is thrown while writing to the file, the file will remain open, preventing anybody from using it, and possibly exhausting the limited number of files that the operating system can keep open at any given time, until finally the garbage collector gets around to collecting the object, which will trigger its finalizer which closes the file, but you don't know when that is (it can easily take hours if you're unlucky). This is why operating system resources such as files should be closed right when your program no longer needs them. That's why InputStreams have a close method, and Java has a try-with-resources statement.
You should assume it does.
Close the writer in a finally block.
I think it's best to always be in the habit of using the finally block to close like so:
public static void warnUser(String name) {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(dir + "warnings.txt", true));
writer.newLine();
writer.write(name);
} catch (Exception e) {
System.out.println(e.getMessage());
System.err.println("error giving warning to: " + name);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
}
}
}
}
Nope , it will not cause a memory leak. The writer object will marked for garbage collection implicitly once the scope of the method ends. But it is a good practice to close the writer object so that the file in question gets closed too.
In cases where exception is thrown check in the finally block if the writer object is null or not. If it has been instantiated then close it . That is what we do in cases where a SQLException is thrown by the code using Jdbc so that the resources being used are released.
finally
{
if (writer!= null)
{
try {
writer.close();
}
catch (IOException exception2)
{
// Do Nothing
}
}
}
.
Basically I am not really sure what is the correct usage of the finally keyword, I only know the textual definition: Guarantees a code will be executed cause sometimes it doesn't. So I was hoping I could get some directions on this particular code:
Also if the try-catch block to call InputStream#close() is unnecesary
try {
inputStream = entity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
responseText = sb.toString();
} catch(IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
You can also use a try-with-resources.
Like so:
try (YourResource resource) {
//Todo...
} catch(YourSpecificException ex) {
//Todo...
}
Your resource declared between parantheses will be automatically closed upon exiting the construction.
You can even declare multiple resources in one go, separate them with a semi-colon. It's all in the above link, really.
The finally block will always be executed whether the exception has arise from try block or not.So finally block is used as post activity.In the code you are using to close the stream.
the finally block ensures that no matter what happens during your try( success or exception), it will always run. This is normally used when cleaning up resources, like InputStream or a Socket
The try with resource paradigm cleans this up, but automatically closing things that are Closeable
try( InputStream inputStream = entity.getContent() )
{
}catch(Exception e)
{
}//declared resource in try automatically closed
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
When try block is executing any exception that occurs will transfer the execution to the catch block then to finally block however if no exception happens in the try the execution of the code will continue after the try to the finally block, here in your code you are trying to use IO resource, which might throws an IO exception if it cannot be occupied by the process then no reference will be assigned to inputStream a finally block must be found to close the IO connection at any case if the resource was occupied or if it is null then nothing, remember finally will always be executed at any case, it is best for closing connection to databases and other resources to release memory too sometimes.
The times I've used finally are generally...
resource handling (IO, DB connections, sockets)
Concurrency (lock releasing, guaranteed counter changes)
finalization (try { } finally { super.finalize(); })
record keeping of states
try {
// Here the guarded area starts
// Here the guarded area ends
} catch {
// This block is executed when an exception occurs inside the guarded area
} finally {
// This block is executed always before leaving try - catch - finally block
// If there is an exception, then first catch block is executed and then finally
}
The code inside finally block you have is a commonly used structure for closing streams. If a stream was created inside guarded area (inputStream != null), then finally block will close it. If there was an exception before inputStream was created, then finally block is executed, but because inputStream == null, the code inside if statement does not execute.
I am beginner in Java programming. But i have code below
Socket socket = serverSocketObj.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
try {
writer.writeLine();
} catch(IOException e ) {
//write to logger here
} finally {
writer.close(); // this throws IOExceptioin too. What to do with it
// Possible memmory leak?
socket.close();
}
When i try to close writer i should handle another Exception. But i don't know what to do with it. Is this Exception impossible in my case? Can i just ignore it?
If you don't know what to do with them, just catch them and log them.
The simplest way of logging them is e.printStackTrace() This way,
at least you'll always see there's a problem if an exception occurs.
Another approach is to just re-throw the exceptions to upper-level code.
E.g. if your method (in which your sample code is) declares to throw IOException,
then there's nothing you should worry about. Let upper-level code worry about it.
Just check if the writer and socket are not null.
Socket socket = serverSocketObj.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
try {
writer.writeLine();
} catch(IOException e ) {
//write to logger here
} finally {
if(writer != null)
writer.close(); // this throws IOExceptioin too. What to do with it
// Possible memmory leak?
if(socket != null)
socket.close();
}
Unfortunately, to make the compiler happy you must catch the potential IOExceptions from the close statements (assuming you don't add IOException to your method's throws clause). (Thank you Mr Goodenough!)
But there's nothing you can really do to "handle" the exception once you have it, other than to log it.
(I'm thinking that the new "try with resources" structure in Java may handle this all a bit cleaner.)
I'm having a problem writing to a file:
FileInputStream fin;
try
{
fin = new FileInputStream ("c:/text.txt");
PrintStream p = new PrintStream(fin);
p.println ("test");
fin.close();
}
catch (IOException ioe)
{
System.err.println (ioe.getMessage);
}
Is there a problem with this code?
You need to use a FileOutputStream.
Get used to the following structure. You'll use it a lot in Java.
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream("c:/text.txt"));
out.println ("test");
} catch (IOException e) {
System.err.println (e.getMessage);
} finally {
if (out != null) {
try { out.close(): } catch (Exception e) { }
}
out = null; // safe but not strictly necessary unless you reuse fin in the same scope
}
At least until ARM blocks hopefully eventuate in Java 7.
As noted, you should close the PrintStream and not the FileOutputStream so the above is a better form to use.
Problems with that code that immediately strike me:
Non-standard formatting.
Awkward variable names.
The exception handling is not good.
Failure to close the file in the case of exceptions. (Use acquire(); try { use(); } finally { release(); }.
Hidden use of default character encoding.
PrintStream swallows exceptions. BufferedOutputStream is better.
Failure to flush the decorator. It may still have data buffered. Although actually in this case you have left the PrintStream in auto-flush mode, which can be a performance issue.
Use / for a Windows path separator. You might be able to get away with it, but it's not good.
So:
FileOutputStream fileOut = new FileOutputStream(
"c:\\text.txt"
);
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
fileOut,
"UTF-8" // Or, say, Charset.defaultCharset()
));
out.write("test");
out.newLine()
out.flush();
} finally {
fileOut.close();
}
The class: FileInputStream is used to read input from a file. If you want to write to the file, you can use: FileOutputStream. If you want to make your life really easy, you can use a BufferedOutputStream as well.
As pointed out, you should close your streams in the finally block. The reason why you want to do that is say your program isn't really small, and it's a larger application. If you forget to close file streams, for example, the application will hold on to it and if you try to do something to it on the file system (read: at least in Windows) you won't be able to it. We've all seen the 'File cannot be deleted because it's still in use' error.
Here's an example of using the FileOutputStream + BufferedOutputStream: http://www.javadb.com/write-to-file-using-bufferedoutputstream.