Best Practice?

F

Felix Goller

Hello,
In another thread I found the following quotation:

"You should only use try/catch. File.Exists() is a waste of time,
because you always _have_ to have the try/catch block anyway. Even if
File.Exists() returns true, the file could disappear before you can
actually open it and load it as an XDocument, and you could experience
other errors as well."

I want to know in common if it is better to _only_ catch exceptions
instead of verifying dependencies like existing files before an operation.
 
S

sloan

I would go a run through (and bookmark) this article:

http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx

Krzysztof will provide some more options.

I kinda understand the comment below, but there are a fewer "higher"
considerations.
I kinda see the point on one hand "the file could disappear", but I don't
think "File.Exists() is a waste of time", because that seems like proactive
coding.
 
W

Wazza

Generaly to the question of do aI use the "check function" or "try /
catch" I would say Use both.

This comes up often in code (not just for files) say altering a value
in a dictionary, should you check the key exists, or just catch an
exception.

The thing to bare in bind if that catching an exception is a very slow
thing (comparable in speed to a database call). If your code was for a
crc generator and was batch running on a list of 5000 files, all of
which were missing, then 5000 failed calls to file.exists() is likely
to happen much quicker than 5000 catch blocks.

I would say "never let a exeption handeler be part of regular program
flow" that is achive everything you expect to see happen in "normal"
operation via logical code and save exception handeling for graceful
behaviour when the proverbial hits the fan.

-Wazza
 
N

not_a_commie

You should use both, especially in non-file-system areas. For example,
popping an item from an empty stack throws an exception. If that's a
common occurrence in your program, you are better of using a locking
mechanism to check the count. With my testing, catching an exception
was 400x slower than an "if" statement to check the count. The
File.Exists() method is obviously more expensive than trivial
properties, but I doubt it is as slow as the exception. If it's a
common occurrence for the file to not exist, use the File.Exists()
test.
 
G

Gregory A. Beamer

"You should only use try/catch. File.Exists() is a waste of time,
because you always _have_ to have the try/catch block anyway. Even if
File.Exists() returns true, the file could disappear before you can
actually open it and load it as an XDocument, and you could experience
other errors as well."

I understand the later part about the XDocument, but the first part is,
overall, just plain stupid, at least in a general sense. I have worked
with files in almost every project at my current assignment and plenty
of projects prior to that, and I have yet to have a file disappear after
I checked existence. And I doubt I will ever see that eventuality if I
continue to stick with the type of jobs I am doing today.

Of course, in context, it might have made sense. I am only seeing a
small part of the post.

if(File.Exists(filePath))
{
StreamReader reader = new StreamReader(filePath);
...
}

In the above example, the likelihood the file will disappear in the
millisecond between statements is most likely null. As said, in context
we might be talking a system where this is not true. In general,
however, I have saved the need for the overhead of exception checking by
doing this. Much lighter code. If exception checking is needed, you can
throw it up in the UI to warn the user (of course that is a gross
oversimplification which will probably unnerve someone ;->).

Peace and Grace,
Greg

--
Vote for Miranda's Christmas Story
http://tinyurl.com/mirandabelieve

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
P

Peter Duniho

sloan said:
I would go a run through (and bookmark) this article:

http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx

Krzysztof will provide some more options.

I kinda understand the comment below, but there are a fewer "higher"
considerations.
I kinda see the point on one hand "the file could disappear", but I don't
think "File.Exists() is a waste of time", because that seems like proactive
coding.

Define "proactive coding". It's not a technical term that has a broadly
accepted meaning or implication.

As far as the advice I gave versus the blog post, you'll note that the
example given for the "tester-doer pattern" involves a scenario where
the condition being tested isn't going to change between the time it's
tested and the time some code is trying to depend on the condition
tested (or, at least it shouldn't...broken multi-threaded code could
violate that assumption).

In other words, in the "tester-doer pattern", you can avoid the
try/catch altogether.

Also note in that example that the technique involves a scenario where a
failure is _expected_. As noted earlier in the blog, exception handling
for dealing with normal code flow should generally be avoided. But when
dealing with files, it is (and should be) practically always the case
that if you have a filename in hand, it's because you _expect_ the file
to be there.

So, while I agree with practically everything written in the blog
article you reference, it's important to understand the difference
between the scenario being asked about here and those described in the
article.

Pete
 
P

Peter Duniho

Gregory said:
I understand the later part about the XDocument, but the first part is,
overall, just plain stupid, at least in a general sense.

As the author of the text you are calling "just plain stupid", I take
offense at your characterization.

The fact is, for file i/o simply checking for the presence of the file
is insufficient even if you could guarantee that the file absolutely
cannot be removed between the time existence is tested and the file is
actually used (which, of course, you can't).

If you can do a test that allows you to remove a try/catch block
altogether, that's certainly a useful thing to do. But in the specific
scenario being asked about, that's not possible. Every file i/o
operation can fail with an exception, and code that doesn't catch the
exception is faulty code.

Typically, this involves a single try/catch at the top level of the file
operation, but of course in some situations it may make sense to check
for errors at a finer granularity.
I have worked
with files in almost every project at my current assignment and plenty
of projects prior to that, and I have yet to have a file disappear after
I checked existence.

Have you also failed to include a try/catch block around your file i/o?
If not, then what has checking the existence of the file done to
improve your code? Nothing. If you have failed to include a try/catch
block around your file i/o, then your code is flawed.
And I doubt I will ever see that eventuality if I
continue to stick with the type of jobs I am doing today.

Of course, in context, it might have made sense. I am only seeing a
small part of the post.

if(File.Exists(filePath))
{
StreamReader reader = new StreamReader(filePath);
...
}

In the above example, the likelihood the file will disappear in the
millisecond between statements is most likely null.

Programming according to statistical likelihood is a very poor practice.
A proper program is coded according to invariants and guarantees.
As said, in context
we might be talking a system where this is not true. In general,
however, I have saved the need for the overhead of exception checking by
doing this. Much lighter code. If exception checking is needed, you can
throw it up in the UI to warn the user (of course that is a gross
oversimplification which will probably unnerve someone ;->).

Exception _checking_ involves practically no overhead at all, and is
required in any case.

If you're going to talk about likelihoods, the fact is that having code
that has a filename in hand but where a file with that filename actually
does not exist is also exceedingly rare. Filenames for files your code
wants to open aren't generally just invented out of thin air; they come
from _somewhere_, with the general expectation that the file _does_ exist.

Pete
 
G

Gregory A. Beamer

As the author of the text you are calling "just plain stupid", I take
offense at your characterization.

Did you read the entire paragraph, or just stop at that point?

I am sorry you did not like my "characterization", but I rarely see an
instance where one must throw an exception handler directly after a file
check. Yes, you do have to code for exceptional behavior, but, in
general (note that word this time), there is no need for this type of
construct:

if(File.Exists(filePath))
{
try
{
StreamReader reader = new StreamReader(filePath);
}
catch (Exception ex)
{
}
}

But, I think this is more about your need to fight than my
"characterization".

If you would like to debate overengineering of solutions, exception
handling at all levels and other topics, then let's start a debate
thread. No reason to start bellyaching about something that was not even
the major point in the answer in this thread.

If you would rather fight this post, as well, I am bowing out. I am
tired of the personal vendetta BS muddying up newsgroups.

Peace and Grace,
Greg

--
Vote for Miranda's Christmas Story
http://tinyurl.com/mirandabelieve

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

*******************************************
| Think outside the box! |
*******************************************
 
P

Peter Duniho

Gregory said:
Did you read the entire paragraph, or just stop at that point?

Of course. That's why my post included a response to text you wrote after.
I am sorry you did not like my "characterization", but I rarely see an
instance where one must throw an exception handler directly after a file
check. Yes, you do have to code for exceptional behavior, but, in
general (note that word this time), there is no need for this type of
construct:

if(File.Exists(filePath))
{
try
{
StreamReader reader = new StreamReader(filePath);
}
catch (Exception ex)
{
}
}

If there is no try/catch around the code calling the above block, you
absolutely MUST have the try/catch after the File.Exists() check. If
you do have a try/catch around the code calling the above block, there
is no need for the call to File.Exists(), nor an interior try/catch block.

But either way, the try/catch has to be there, and either way, the call
to File.Exists() adds nothing to the code except one more line of code
that has to be maintained.
But, I think this is more about your need to fight than my
"characterization".

You are free to think whatever you want, no matter how wrong your
thoughts are.
If you would like to debate overengineering of solutions, exception
handling at all levels and other topics, then let's start a debate
thread. No reason to start bellyaching about something that was not even
the major point in the answer in this thread.

What do you think "the major point in the answer in this thread" is, if
not the question of whether the call to File.Exists() is necessary or not?
If you would rather fight this post, as well, I am bowing out. I am
tired of the personal vendetta BS muddying up newsgroups.

Vendetta? I have no idea where you get that, unless you're pursuing a
vendetta yourself (in which case, it's completely within your control to
avoid the occurrence).

Pete
 
P

Peter Duniho

Gregory said:
Now I see an example of proper "characterization".

Yes, you have.

Nowhere have I used insults to describe you or your posts, and the only
"thought" that I have described as "wrong" is the one that pertains to
something that I without question know much more about than you (i.e.
the question of whether my reply is "about my need to fight").

If you would restrict your comments to that sort of approach, you would
find yourself at the receiving end of what you apparently find to be
disagreeable statements much less often.

Pete
 
R

Roger

File.Exists() returns true, the file could disappear before you can

even if it exists, it may not open if it is open
exclusively.
and you could experience other errors as well."
yes, that is true

Roger
 
R

Registered User

Hello,
In another thread I found the following quotation:

"You should only use try/catch. File.Exists() is a waste of time,
because you always _have_ to have the try/catch block anyway. Even if
File.Exists() returns true, the file could disappear before you can
actually open it and load it as an XDocument, and you could experience
other errors as well."

I want to know in common if it is better to _only_ catch exceptions
instead of verifying dependencies like existing files before an operation.

The "_only_" makes the obvious answer no. It is always wise to
evaluate the state and value of dependencies before their use.
Structured exception handling can then wrapper the normal flow of
control which relies upon the dependencies.

regards
A.G.
 
P

Paul

My understanding is that File.Exists does not throw an exception but just
returns false, and almost ensure that the file is there when you come to
work on it. So its use is not moot because the idea is it should prevent
more exceptions been thrown than needed. Thats my take on it anyway.

So use both. MSDN explains this quite clearly I believe.
 
J

JeffWhitledge

"You should only use try/catch.  File.Exists() is a waste of time,
because you always _have_ to have the try/catch block anyway.  Even if
File.Exists() returns true, the file could disappear before you can
actually open it and load it as an XDocument, and you could experience
other errors as well."

I want to know in common if it is better to _only_ catch exceptions
instead of verifying dependencies like existing files before an operation..

In many cases, preconditions can be ensured without exception
handling. For example, you would almost never need to catch an
ArgumentNullException. It is usually possible to *know* that an object
reference is not null at the time that object reference is used
without checking it and without error handling. And if you don't know
it for a fact, then you can always check to see if it's a null
reference. Thus there's no reason to catch the exception.

This is *never* the case for IO.

External things like files are a special case. The file system is out
of your control in a way that other things (like collection objects
for example) are not. There is no way to ensure that preconditions are
always met when dealing with files (or TCP connections, etc.).

I would say that in most cases it is not really helpful to call
File.Exists(), since it provides no assurances at all. A file can
exist, but still be unreadable, because of security issues, locking,
etc. A file can exist one second and be gone the next. A connection to
a network share could drop in the middle of reading the file. There
are many ways IO can fail, and a failure to handle those exceptions
properly is a bug.

In spite of this, there are a few cases when it might make sense to
call File.Exists(). For example, if the logic of your process depends
in some way on the existance of a file, such as a signaling file
created by a batch application. Or if a long-running process could
fail at the end because of the existance or non-existance of a file,
and options could be taken at the beginning of the process to mitigate
the error.

But if the file is expected to be there as part of the process, then
File.Exists() is pointless. If you're planning to open the file, then
checking its existance is pointless, because you have to handle the
other exceptions anyway. If the user has just selected the file in the
file-open dialog box, then calling File.Exists() is just plain nuts.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top