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;
Related
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);
}
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;
I've got code that looks like this because the only reliable way for me to check if some data is an image is to actually try and load it like an image.
static void DownloadCompleted(HttpConnection conn) {
Image img;
HtmlDocument doc;
try {
img = Image.FromStream(conn.Stream);
} catch {
try {
doc = new HtmlDocument();
doc.Load(conn.Stream);
} catch { return; }
ProcessDocument(doc);
return;
}
ProcessImage(img);
return;
}
Which looks down right terrible!
What's a nice way of handling these situations? Where you're basically forced to use an exception like an if statement?
Your logical structure is
if( /* Loading Image Fails */ )
/* Try Loading HTML */
so I would try to make the code read that way. It would probably be cleanest (though admittedly annoyingly verbose) to introduce helper methods:
bool LoadImage()
{
Image img;
try
{
img = Image.FromStream(conn.Stream);
}
catch( NotAnImageException /* or whatever it is */ )
{
return false;
}
ProcessImage(img);
return true;
}
bool LoadDocument()
{
// etc
}
So you can write
if( !LoadImage() )
LoadDocument();
or extend it to:
if( !LoadImage() && !LoadDocument() )
{
/* Complain */
}
I think empty catch blocks, the way you've coded them, are a very bad idea in general. You're swallowing an exception there. No one will ever know that something is amiss the way you've coded it.
My policy is that if I can't handle and recover from an exception, I should simply allow it to bubble up the call stack to a place where it can be handled. That might mean nothing more than logging the error, but it's better than hiding the error.
If unchecked exceptions are the rule in .NET, I'd recommend that you use just one try/catch block when you must within a single method. I agree - multiple try/catch blocks in a method is ugly and cluttering.
I'm not sure what your code is trying to do. It looks like you're using exceptions as logic: "If an exception isn't thrown, process and return an image; if an exception IS thrown, process and return an HTML document." I think this is a bad design. I'd refactor it into two methods, one each for an image and HTML, and not use exceptions instead of an "if" test.
I like the idea of Eric's example, but I find the implementation ugly: doing work in an if and having a method that does work return a boolean looks very ugly.
My choice would be a method that returns Images, and a similar method
Image LoadImage(HttpConnection conn)
{
try
{
return Image.FromStream(conn.Stream);
}
catch(NotAnImageException)
{
return null;
}
}
and do the work in the original method:
static void DownloadCompleted(HttpConnection conn)
{
Image img = LoadImage(conn);
if(img != null)
{
ProcessImage(img);
return;
}
HtmlDocument doc = LoadDocument(conn);
if(doc != null)
{
ProcessDocument(doc)
return;
}
return;
}
In conjunction to duffymo's answer, if you're dealing with
File input/output, use IOException
Network sockets, use SocketException
XML, use XmlException
That would make catching exceptions tidier as you're not allowing it to bubble up to the generic catch-all exception. It can be slow, if you use the generic catch-all exception as the stack trace will be bubbling up and eating up memory as the references to the Exception's property, InnerException gets nested as a result.
Either way, craft your code to show the exception and log it if necessary or rethrow it to be caught by the catch-all exception...never assume the code will not fail because there's plenty of memory, plenty of disk and so on as that's shooting yourself in the foot.
If you want to design your own Exception class if you are building a unique set of classes and API, inherit from the ApplicationException class.
Edit:
I understand better what the OP is doing...I suggest the following, cleaner implementation, notice how I check the stream to see if there's a HTML tag or a DOC tag as part of XHTML...
static void DownloadCompleted(HttpConnection conn) {
Image img;
HtmlDocument doc;
bool bText = false;
using (System.IO.BinaryReader br = new BinaryReader(conn.Stream)){
char[] chPeek = br.ReadChars(30);
string s = chPeek.ToString().Replace(" ", "");
if (s.IndexOf("<DOC") > 0 || s.IndexOf("<HTML") > 0){
// We have a pure Text!
bText = true;
}
}
if (bText){
doc = new HtmlDocument();
doc.Load(conn.Stream);
}else{
img = Image.FromStream(conn.Stream);
}
}
Increase the length if you so wish depending on how far into the conn.Stream indicating where the html tags are...
Hope this helps,
Best regards,
Tom.
There is no need to try to guess the content type of an HTTP download, which is why you are catching exceptions here. The HTTP protocol defines a Content-Type header field which gives you the MIME type of the downloaded content.
Also, a non-seekable stream can only be read once. To read the content of a stream multiple times, you would have to copy it to a MemoryStream and reset it before each read session with Seek(0, SeekOrigin.Begin).
Answering your exact question: you don't need a catch block at all, try/finally block will work just fine without a catch block.
try
{
int i = 0;
}
finally {}
I would much prefer to do this without catching an exception in LoadXml() and using this results as part of my logic. Any ideas for a solution that doesn't involve manually parsing the xml myself? I think VB has a return value of false for this function instead of throwing an XmlException. Xml input is provided from the user. Thanks much!
if (!loaded)
{
this.m_xTableStructure = new XmlDocument();
try
{
this.m_xTableStructure.LoadXml(input);
loaded = true;
}
catch
{
loaded = false;
}
}
Just catch the exception. The small overhead from catching an exception drowns compared to parsing the XML.
If you want the function (for stylistic reasons, not for performance), implement it yourself:
public class MyXmlDocument: XmlDocument
{
bool TryParseXml(string xml){
try{
ParseXml(xml);
return true;
}catch(XmlException e){
return false;
}
}
Using a XmlValidatingReader will prevent the exceptions, if you provide your own ValidationEventHandler.
I was unable to get XmlValidatingReader & ValidationEventHandler to work. The XmlException is still thrown for incorrectly formed xml. I verified this by viewing the methods with reflector.
I indeed need to validate 100s of short XHTML fragments per second.
public static bool IsValidXhtml(this string text)
{
bool errored = false;
var reader = new XmlValidatingReader(text, XmlNodeType.Element, new XmlParserContext(null, new XmlNamespaceManager(new NameTable()), null, XmlSpace.None));
reader.ValidationEventHandler += ((sender, e) => { errored = e.Severity == System.Xml.Schema.XmlSeverityType.Error; });
while (reader.Read()) { ; }
reader.Close();
return !errored;
}
XmlParserContext did not work either.
Anyone succeed with a regex?
If catching is too much for you, then you might want to validate the XML beforehand, using an XML Schema, to make sure that the XML is ok, But that will probably be worse than catching.
AS already been said, I'd rather catch the exception, but using XmlParserContext, you could try to parse "manually" and intercept any anomaly; however, unless you're parsing 100 xml fragments per second, why not catching the exception?
Often I find myself interacting with files in some way but after writing the code I'm always uncertain how robust it actually is. The problem is that I'm not entirely sure how file related operations can fail and, therefore, the best way to handle exceptions.
The simple solution would seem to be just to catch any IOExceptions thrown by the code and give the user an "Inaccessible file" error message, but is it possible to get a bit more fine-grained error messages? Is there a way to determine the difference between such errors as a file being locked by another program and the data being unreadable due to a hardware error?
Given the following C# code, how would you handle errors in a user friendly (as informative as possible) way?
public class IO
{
public List<string> ReadFile(string path)
{
FileInfo file = new FileInfo(path);
if (!file.Exists)
{
throw new FileNotFoundException();
}
StreamReader reader = file.OpenText();
List<string> text = new List<string>();
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
reader.Close();
reader.Dispose();
return text;
}
public void WriteFile(List<string> text, string path)
{
FileInfo file = new FileInfo(path);
if (!file.Exists)
{
throw new FileNotFoundException();
}
StreamWriter writer = file.CreateText();
foreach(string line in text)
{
writer.WriteLine(line);
}
writer.Flush();
writer.Close();
writer.Dispose();
}
}
...but is it possible to get a bit more fine-grained error messages.
Yes. Go ahead and catch IOException, and use the Exception.ToString() method to get a relatively relevant error message to display. Note that the exceptions generated by the .NET Framework will supply these useful strings, but if you are going to throw your own exception, you must remember to plug in that string into the Exception's constructor, like:
throw new FileNotFoundException("File not found");
Also, absolutely, as per Scott Dorman, use that using statement. The thing to notice, though, is that the using statement doesn't actually catch anything, which is the way it ought to be. Your test to see if the file exists, for instance, will introduce a race condition that may be rather vexing. It doesn't really do you any good to have it in there. So, now, for the reader we have:
try {
using (StreamReader reader = file.OpenText()) {
// Your processing code here
}
} catch (IOException e) {
UI.AlertUserSomehow(e.ToString());
}
In short, for basic file operations:
1. Use using
2, Wrap the using statement or function in a try/catch that catches IOException
3. Use Exception.ToString() in your catch to get a useful error message
4. Don't try to detect exceptional file issues yourself. Let .NET do the throwing for you.
The first thing you should change are your calls to StreamWriter and StreamReader to wrap them in a using statement, like this:
using (StreamReader reader = file.OpenText())
{
List<string> text = new List<string>();
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
}
This will take care of calling Close and Dispose for you and will actually wrap it in a try/finally block so the actual compiled code looks like this:
StreamReader reader = file.OpenText();
try
{
List<string> text = new List<string>();
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
}
finally
{
if (reader != null)
((IDisposable)reader).Dispose();
}
The benefit here is that you ensure the stream gets closed even if an exception occurs.
As far as any more explicit exception handling, it really depends on what you want to happen. In your example you explicitly test if the file exists and throw a FileNotFoundException which may be enough for your users but it may not.
Skip the File.Exists(); either handle it elsewhere or let CreateText()/OpenText() raise it.
The end-user usually only cares if it succeeds or not. If it fails, just say so, he don't want details.
I haven't found a built-in way to get details about what and why something failed in .NET, but if you go native with CreateFile you have thousands of error-codes that can tell you what went wrong.
I don't see the point in checking for existence of a file and throwing a FileNotFoundException with no message. The framework will throw the FileNotFoundException itself, with a message.
Another problem with your example is that you should be using the try/finally pattern or the using statement to ensure your disposable classes are properly disposed even when there is an exception.
I would do this something like the following, catch any exception outside the method, and display the exception's message :
public IList<string> ReadFile(string path)
{
List<string> text = new List<string>();
using(StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
text.Add(reader.ReadLine());
}
}
return text;
}
I would use the using statement to simplify closing the file. See MSDN the C# using statement
From MSDN:
using (TextWriter w = File.CreateText("log.txt")) {
w.WriteLine("This is line one");
w.WriteLine("This is line two");
}
using (TextReader r = File.OpenText("log.txt")) {
string s;
while ((s = r.ReadLine()) != null) {
Console.WriteLine(s);
}
}
Perhaps this is not what you are looking for, but reconsider the kind you are using exception handling. At first exception handling should not be treated to be "user-friendly", at least as long as you think of a programmer as user.
A sum-up for that may be the following article http://goit-postal.blogspot.com/2007/03/brief-introduction-to-exception.html .