try...catch inside finally when releasing resource? - c#

I want to write a String to a Unicode file. My code in Java is:
public static boolean saveStringToFile(String fileName, String text) {
BufferedWriter out = null;
boolean result = true;
try {
File f = new File(fileName);
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(f), "UTF-8"));
out.write(text);
out.flush();
} catch (Exception ex) {
result = false;
} finally {
if (out != null)
try {
out.close();
} catch (IOException e) {
// nothing to do! couldn't close
}
}
return result;
}
Update
Now compare it to C#:
private static bool SaveStringToFile(string fileName, string text)
{
using (StreamWriter writer = new StreamWriter(fileName))
{
writer.Write(text);
}
}
or even try..catch form would be:
private static bool SaveStringToFile(string fileName, string text)
{
StreamWriter writer = new StreamWriter(fileName);
try
{
writer.Write(text);
}catch (Exception ex)
{
return false;
}
finally
{
if (writer != null)
writer.Dispose();
}
}
Maybe it's because I'm from the C# and .Net world. But is this the right way to write a String to a file? It's just too much code for such simple task. In C#, I would say to just out.close(); and that was it but it seems a bit strange to add a try..catch inside a finally statement. I added the finally statement to close the file (resource) no matter what happens. To avoid using too much resource. Is this the right way in Java? If so, why close throws exception?

You are correct in that you need to call the close() in the finally block and you also need to wrap this is a try/catch
Generally you will write a utility method in you project or use a utility method from a library like http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.Closeable) to closeQuietly .i.e. ignore any throw exception from the close().
On an additional note Java 7 has added support for try with resources which removes the need to manually close the resouce - http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Yes, There is nothing strange about Try catch inside finally() in java. close() may throw IoException for various reasons, thats why it has to enclosed by try catch blocks. There is an improved solution to this problem of yours, in the latest java SE 7 Try with resources

The Java equivalent to the using statement is the try-with-resources statement added in Java 7:
public static void saveStringToFile(String fileName, String text) throws IOException {
try (Writer w = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8")) {
w.write(text);
}
}
The try-with-resources will automatically close the stream (which implicity flushes it), and throw any exceptions encountered when doing so.
A BufferedWriter is not necessary if you do a single call to write anyway (its purpose is to combine several writes to the underlying stream to reduce the number of system calls, thereby improving performance).
If you insist on handling errors by returning false, you can add a catch clause:
public static boolean saveStringToFile(String fileName, String text) {
try (Writer w = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8")) {
w.write(text);
return true;
} catch (IOException e) {
return false;
}
}

This should do the trick. If you want to manage exception with complex behavior - then create StreamWriter
public static bool saveStringToFile(String fileName, String text)
{
try
{
File.WriteAllText(fileName, text, Encoding.UTF8);
}
catch (IOException exp)
{
return false;
}
return true;
}

So, what is the question? There is no right or wrong way. Can close even throw an IO Exception ? What do you do then? I generally like non rethrowing of any sort not at all.
The problem is - you just swallow an IO Exception on Close - good. CAN you live with that blowing? If not you have a problem, if yes - nothing wrong.
I never did that, but - again, that depends on your business case.

arch = new File("path + name");
arch.createNewFile();
FileOutputStream fos = new FileOutputStream(arch);
fos.write("ur text");
fos.close();
my way.

The best way to avoid that is putting your out.close() after out.flush() and the process is automatically handled if the close fails. Or use this is better (what I am using) :
File file = ...
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file));
...
finally {
if (out != null) {
out.close();
}
}
}

If you want a minimum of code you can use FileUtils.writeStringToFile
FileUtils.writeStringToFile(new File(fileName), text);
and I wouldn't use boolean as it rarely a good idea to ignore either the fact an error occured or the reason it occured which is in the message of the exception. Using a checked Exception ensures the caller will always deal with such error correctly and can log meaningful error messages as to why.
To save the file using a specific CharSet
try {
FileUtils.writeStringToFile(new File(fileName), text, "UTF-8");
} catch(IOException ioe) {
Logger.getLogger(getClass()).log(Level.WARNING, "Failed to write to " + fileName, ioe);
}

Related

How can I have an exception show in debugging output that doesn't cause a "catch"

This may be a basic question but I have not been able to find an answer from searching. I have code that is causing an exception to be written to the Output -> Debug window in Visual Studio. My try...catch is proceeding to the next line of code anyway. The exception is with a NuGet package.
Does this mean an exception is happening in the NuGet package and is handled by the Nuget package? How can I troubleshoot this further?
private void HandleStorageWriteAvailable(IXDocument doc)
{
using IStorage storage = doc.OpenStorage(StorageName, AccessType_e.Write);
{
Debug.WriteLine("Attempting to write to storage.");
try
{
using (Stream str = storage.TryOpenStream(EntityStreamName, true))
{
if (str is not null)
{
try
{
string test = string.Concat(Enumerable.Repeat("*", 100000));
var xmlSer = new XmlSerializer(typeof(string));
xmlSer.Serialize(str, test);
}
catch (Exception ex)
{
Debug.WriteLine("Something bad happened when trying to write to the SW file.");
Debug.WriteLine(ex);
}
}
else
{
Debug.WriteLine($"Failed to open stream {EntityStreamName} to write to.");
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
}
The exception happens on the line using (Stream str = storage.TryOpenStream(EntityStreamName, true)) when the exception happens the code proceeds to the next line not the catch.
Is this normal behaviour if that exception is being handled by something else? I've never seen this before.
In general, a method called TrySomething will be designed so that it won't throw an exception, but return some sort of error code instead.
Check for example the Dictionary class : it has an Add method which can throw an ArgumentException if the key already exists, and a TryAdd method which instead just returns false.
Chances are, your IStorage implementation of TryOpenStream also has an OpenStream method, and the Try version is just a try/catch wrapper which outputs the error to the Console in case of error.
How do you know it happens on that line?
However there is a setting that enables breaking handled exception in "Exception Settings" dialog (Ctrl+Alt+E). For each type of exception you can control. Here is a link that explain how it works : https://learn.microsoft.com/en-us/visualstudio/debugger/managing-exceptions-with-the-debugger?view=vs-2022

What exceptions can occur when saving an XDocument?

In my C# application I'm using the following statement:
public void Write(XDocument outputXml, string outputFilename) {
outputXml.Save(outputFilename);
}
How can I find out which exceptions the Save method might throw? Preferably right in Visual Studio 2012 or alternatively in the MSDN documentation.
XDocument.Save does not give any references. It does for other methods, e.g. File.IO.Open.
Unfortunately MSDN do not have any information about exceptions thrown by XDocument and many other types from System.Xml.Linq namespace.
But here is how saving implemented:
public void Save(string fileName, SaveOptions options)
{
XmlWriterSettings xmlWriterSettings = XNode.GetXmlWriterSettings(options);
if ((declaration != null) && !string.IsNullOrEmpty(declaration.Encoding))
{
try
{
xmlWriterSettings.Encoding =
Encoding.GetEncoding(declaration.Encoding);
}
catch (ArgumentException)
{
}
}
using (XmlWriter writer = XmlWriter.Create(fileName, xmlWriterSettings))
Save(writer);
}
If you will dig deeper, you'll see that there is large number of possible exceptions. E.g. XmlWriter.Create method can throw ArgumentNullException. Then it creates XmlWriter which involves FileStream creation. And here you can catch ArgumentException, NotSupportedException, DirectoryNotFoundException, SecurityException, PathTooLongException etc.
So, I think you should not try to catch all this stuff. Consider to wrap any exception in application specific exception, and throw it to higher levels of your application:
public void Write(XDocument outputXml, string outputFilename)
{
try
{
outputXml.Save(outputFilename);
}
catch(Exception e)
{
throw new ReportCreationException(e); // your exception type here
}
}
Calling code can catch only ReportCreationException and log it, notify user, etc.
If the MSDN doesn't state any I guess that Class won't throw any exception. Although, I don't think that this object will be responsible for writing the actual file to disk. So you might receive exceptions from other classes used by XDocument.Save();
To be on the safe side, I would trap all exceptions and try out some obvious erratic instructions, see below.
try
{
outputXml.Save("Z:\\path_that_dont_exist\\filename");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Here, catching Exception will catch any types of exceptions.

Trouble with handling exceptions with streamreader

I'm having some trouble with StreamReader, I have a settings file where I save settings in. I want to open and close the file on a way that I also can handle exceptions.
When the file can't be loaded I want to return for now false.
I created a function that loads the file for me:
private bool LoadSettingsFile(out StreamReader SettingsFile)
{
try
{
SettingsFile = new StreamReader("Settings.txt");
return true;
}
catch
{
//Going to solve the exception later, but if I can't I want to return false.
SettingsFile = new StreamReader(); //You need to assign StreamReader, but you need to open a file for that.
//'System.IO.StreamReader' does not contain a constructor that takes 0 arguments
return false;
}
}
I call the function on this way:
StreamReader SettingsFile;
if (!LoadSettingsFile(out SettingsFile))
return false;
How can I avoid or solve this?
If you are unable to open the file, why would you want to return a StreamReader instance? Surely you would want to return null. Also, it's never really a good idea to do a catch-all in your exception handling, be more specific e.g.
private bool LoadSettingsFile(out StreamReader settingsFile)
{
try
{
settingsFile = new StreamReader("Settings.txt");
return true;
}
catch (IOException) // specifically handle any IOExceptions
{
settingsFile = null;
return false;
}
}
This is arguably bad practise in that, in general, .NET code prefers "throwing exceptions" over "returning failure." The reason for this is that, if you are "returning failure," you rely on the consumer of your code to recognise this and do something about it. If you throw an exception and the consumer of your code ignores it, the application will fail - which is often more desireable than for it to continue in an undefined state.
In your case, the problem is that you're forced to assign to your out parameter even when there is no sensible value to assign there. One obvious suggestion is to assign null instead of trying to fake a StreamReader. Alternatively, you could create an empty MemoryStream and return a reader for that, but this is going to some extreme lengths to cover up the fact that the variable has no meaning in a failure case and should not be set.
Ultimately I'd suggest you allow the exception to bubble rather than returning a bool to indicate failure - or alternatively, return the StreamReader for success and return null in the case of failure.
Just set SettingsFile = null before entering into the Try/Catch block. Presumably by returning false you're handling this condition at a higher level, so SettingsFile will never be used. So your code would look like this:
private bool LoadSettingsFile(out StreamReader SettingsFile)
{
SettingsFile = null;
try
{
SettingsFile = new StreamReader("Settings.txt");
return true;
}
catch
{
//Handle Exception Here
return false;
}
}
You can try
private StreamReader LoadSettingsFile()
{
try
{
return new StreamReader("Settings.txt");
}
catch
{
return null;
}
}
and then
StreamReader sr = LoadSettingsFile();
if (sr == null) return false;

Letting an exception to bubble up

How to correctly let an exception to bubble up?
If I use Try-Catch when calling a method, is just throwing an exception inside a method like not trying to catch it at all?
For illustration: Are these approaches do the same work?
Example 1:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
...
}
Example 2:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
try
{
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
}
catch (Exception)
{
throw;
}
...
}
Yes, those 2 approaches have almost the same effect; rethrowing will unwind the stack of the exception - meaning the stack frames "below" the method where the throw; will be discarded. They'll still be in the stack trace, but you won't be able to access their local variables in the debugger unless you break on thrown exceptions.
A catch/throw block like the one below where you don't do anything with the exception (like logging), is useless:
catch (Exception)
{
throw;
}
Remove it to clean up, in both your samples. In general, avoid entering a catch block if possible
And your method has another exception related problem, it does not free resources properly. The tr2.Close(); belongs in a finally clause but it's much easier to let the compiler handle that with a using() {} block :
void MyFileHandlingMethod()
{
...
using (TextReader tr2 = new StreamReader(nfilepath))
{
resultN = tr2.ReadLine();
} //tr2.Dispose() inserted automatically here
...
}
First of all you should use the using block with resources as this will take care of closing your resources correctly. The second example is pretty much useless as you don't do any work in the exception handler. Either you should remove it, or wrap it in another Exception to add some information.
Yes, the result is the same.
However, both will result in an unclosed stream if there is an error while reading it. You should use a using block or a try ... finally to make sure that the stream is closed:
using (TextReader tr2 = new StreamReader(nfilepath)) {
resultN = tr2.ReadLine();
}
Note that there is no Close in this code. The using block will dispose the StreamReader, which will close the stream.
The using block is compiled into a try ... finally which it uses to make sure that the StreamReader is always disposed, but the exception will bubble up to the calling method.
I suggest you use your first example, with these changes:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...";
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
throw; // rethrow the same exception.
}
// no need for second catch}
You probably want to rethrow the exception once you have logged it, because you are not doing any actual recovery from the error.

Where the finally is necessary?

I know how to use try-catch-finally. However I do not get the advance of using finally as I always can place the code after the try-catch block.
Is there any clear example?
It's almost always used for cleanup, usually implicitly via a using statement:
FileStream stream = new FileStream(...);
try
{
// Read some stuff
}
finally
{
stream.Dispose();
}
Now this is not equivalent to
FileStream stream = new FileStream(...);
// Read some stuff
stream.Dispose();
because the "read some stuff" code could throw an exception or possibly return - and however it completes, we want to dispose of the stream.
So finally blocks are usually for resource cleanup of some kind. However, in C# they're usually implicit via a using statement:
using (FileStream stream = new FileStream(...))
{
// Read some stuff
} // Dispose called automatically
finally blocks are much more common in Java than in C#, precisely because of the using statement. I very rarely write my own finally blocks in C#.
You need a finally because you should not always have a catch:
void M()
{
var fs = new FileStream(...);
try
{
fs.Write(...);
}
finally
{
fs.Close();
}
}
The above method does not catch errors from using fs, leaving them to the caller. But it should always close the stream.
Note that this kind of code would normally use a using() {} block but that is just shorthand for a try/finally. To be complete:
using(var fs = new FileStream(...))
{
fs.Write(...);
} // invisible finally here
try
{
DoSomethingImportant();
}
finally
{
ItIsRidiculouslyImportantThatThisRuns();
}
When you have a finally block, the code therein is guaranteed to run upon exit of the try. If you place code outside of the try/catch, that is not the case. A more common example is the one utilized with disposable resources when you use the using statement.
using (StreamReader reader = new StreamReader(filename))
{
}
expands to
StreamReader reader = null;
try
{
reader = new StreamReader(filename);
// do work
}
finally
{
if (reader != null)
((IDisposable)reader).Dispose();
}
This ensures that all unmanaged resources get disposed and released, even in the case of an exception during the try.
*Note that there are situations when control does not exit the try, and the finally would not actually run. As an easy example, PowerFailureException.
Update: This is actually not a great answer. On the other hand, maybe it is a good answer because it illustrates a perfect example of finally succeeding where a developer (i.e., me) might fail to ensure cleanup properly. In the below code, consider the scenario where an exception other than SpecificException is thrown. Then the first example will still perform cleanup, while the second will not, even though the developer may think "I caught the exception and handled it, so surely the subsequent code will run."
Everybody's giving reasons to use try/finally without a catch. It can still make sense to do so with a catch, even if you're throwing an exception. Consider the case* where you want to return a value.
try
{
DoSomethingTricky();
return true;
}
catch (SpecificException ex)
{
LogException(ex);
return false;
}
finally
{
DoImportantCleanup();
}
The alternative to the above without a finally is (in my opinion) somewhat less readable:
bool success;
try
{
DoSomethingTricky();
success = true;
}
catch (SpecificException ex)
{
LogException(ex);
success = false;
}
DoImportantCleanup();
return success;
*I do think a better example of try/catch/finally is when the exception is re-thrown (using throw, not throw ex—but that's another topic) in the catch block, and so the finally is necessary as without it code after the try/catch would not run. This is typically accomplished with a using statement on an IDisposable resource, but that's not always the case. Sometimes the cleanup is not specifically a Dispose call (or is more than just a Dispose call).
The code put in the finally block is executed even when:
there are return statements in the try or catch block
OR
the catch block rethrows the exception
Example:
public int Foo()
{
try
{
MethodThatCausesException();
}
catch
{
return 0;
}
// this will NOT be executed
ReleaseResources();
}
public int Bar()
{
try
{
MethodThatCausesException();
}
catch
{
return 0;
}
finally
{
// this will be executed
ReleaseResources();
}
}
you don't necessarily use it with exceptions. You may have try/finally to execute some clean up before every return in the block.
The finally block always is executed irrespective of error obtained or not. It is generally used for cleaning up purposes.
For your question, the general use of Catch is to throw the error back to caller, in such cases the code is finally still executes.
The finally block will always be executed even if the exception is re-thrown in the catch block.
If an exception occurs (or is rethrown) in the catch-block, the code after the catch won't be executed - in contrast, code inside a finally will still be executed.
In addition, code inside a finally is even executed when the method is exited using return.
Finally is especially handy when dealing with external resources like files which need to be closed:
Stream file;
try
{
file = File.Open(/**/);
//...
if (someCondition)
return;
//...
}
catch (Exception ex)
{
//Notify the user
}
finally
{
if (file != null)
file.Close();
}
Note however, that in this example you could also use using:
using (Stream file = File.Open(/**/))
{
//Code
}
For example, during the process you may disable WinForm...
try
{
this.Enabled = false;
// some process
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
this.Enabled = true;
}
I am not sure how it is done in c#, but in Delphi, you will find "finally" very often. The keyword is manual memory management.
MyObject := TMyObject.Create(); //Constructor
try
//do something
finally
MyObject.Free();
end;

Categories