Re: A better file copy function (was Re: copying files )
- From: Duncan McNiven <spamtrap@xxxxxxxxxxxxxxxxxx>
- Date: Wed, 24 Aug 2005 20:59:57 +0300
On Tue, 23 Aug 2005 11:38:00 -0700, "Are you Crazy!"
<You@xxxxxxxxxxxxxxxxxxxx> wrote:
>Duncan McNiven wrote:
>> How so? What is wrong with GetLastError?
>
>Nothing is wrong with it, it just creates a situation where you have to
>call yet another API fuction when you could simply handle the problem
>directly, and know exactly where the thing failed.
I don't see that as a problem. You do know immediately the call to
CopyFileEx failed. Calling an API function to get the error code is no
different to calling one of your own functions to decode the encoded
return value from your own function.
>------------------- From the WIN API Refernce --------------------
><snip>
>
>Ask you can see there are many side effects that can be introduced.
Actually I can't see a single side effect. The first paragraph is just
saying that the error code returned varies according to the function
that set the error. No surprise there. The second paragraph is just
saying that a range of error codes is reserved for application-defined
errors. No issue.
>So while calling this is certainly one way to do things, I believe that
>well written functions are the better way to go.
API Calls are well-written and well-documented functions that have
mainly existed for years and been tested by millions of developers
world-wide. If an API call exists to do what you want then surely it
makes sense to use it.
>You get direct feedback, and the code simply reads better and is far more informative
>then having to work your way through 4 bytes of data to figure out if an
>error even occured.
We clearly have very different ideas about what constitutes readable
code. I think a maintenance programmer, possibly with limited
experience, is going to understand a call to a standard API function a
lot quicker than they will understand a lengthy function that returns
a complex encoded value.
>Additionaly, as the very first line states, you should call this when
>you _know_ an error has occured,
Yes, when CopyFileEx returns zero.
>Even calling this, you then have to parse out what kind of an error code
>you are getting.
Correct me if I am wrong but I think you misunderstand the value
returned by GetLastError. It is just an error code. You don't have to
parse anything. For example:
procedure DemoCopyFileEx(CopyFrom : string; CopyTo : string);
begin
if not CopyFileEx(
PChar(CopyFrom),
PChar(CopyTo),
nil,nil,nil,
COPY_FILE_FAIL_IF_EXISTS) then
MessageBox(
0,
pChar(SysErrorMessage(GetLastError)),
'Error',
mb_OK);
end;
This gives you file copying plus fairly meaningful error reporting,
yet the time spent writing and debugging using this approach will be
minimal.
Of course you might want to enhance the error reporting. Again, that
is easy, with no parsing required. This would give you a start.
procedure DemoExCopyFileEx(CopyFrom : string; CopyTo : string);
begin
if not CopyFileEx(
PChar(CopyFrom),
PChar(CopyTo),
nil,nil,nil,
COPY_FILE_FAIL_IF_EXISTS) then
case GetLastError of
ERROR_FILE_NOT_FOUND :
MessageBox(
0,
pChar(CopyFrom+' : ' +
SysErrorMessage(ERROR_FILE_NOT_FOUND)),
'Error',
mb_OK);
ERROR_FILE_EXISTS :
MessageBox(
0,
pChar(CopyTo + ' : ' +
SysErrorMessage(ERROR_FILE_EXISTS)),
'Error',
mb_OK);
ERROR_DISK_FULL :
MessageBox(
0,
pChar(CopyTo + ' : ' +
SysErrorMessage(ERROR_DISK_FULL)),
'Error',
mb_OK);
else
MessageBox(
0,
PChar(IntToStr(GetLastError) + ' : ' +
SysErrorMessage(GetLastError)),
'Error',
mb_OK);
end;
end;
>Exceptions and error codes are actualy one and the same. The whole
>exception handling bit is quite the same thing as an error code, it
>simply wraps it in a nifty structure.
No, exceptions come with compiler magic to redirect flow of execution
when an execption occurs, and that makes exceptions MUCH more powerful
than simple error codes. Consider what happens if I use your function
in a non-visual file-copying component. What should I do about errors?
I have no choice except to trap your return value, extract the error
code from it, check if it is something I can handle and if not,
somehow wrap it up together with any status code my component needs to
return, and then return that to the code that uses my component.
Now suppose Fred uses my component in a non-visual directory-copying
component. Fred has to do exactly the same as I did. Then Joe uses
Fred's component in a non-visual disk-copying component. Joe has to
repeat the same error handling work yet gain. Then Harry uses Joe's
component in a back-up application. At last there is code that can
handle the error, displaying or logging a message or whatever. With
exceptions, Joe, Fred and I would just ignore exceptions we can't
handle and they would automatically propogate out to Harry's
exception-handler. Think of all the work that saves us, and the
reduced scope for errors.
>It allows you to know the point in which the copy failed
True, but you know that from the error code anyway. If you are copying
a file and get the error that the file doesn't exist, you know where
the copy failed.
>and it will also tell you what the OS error was.
As does CopyFileEx / GetLastError.
>Parsing is going to required no matter what method you use and
>parsing my return value is much easier then parsing the result
>from GetLastError.
See my example code above. No parsing is necessary to use the result
from GetLastError.
>I never trust windows to actualy do what it says it will.
Oh come on, of course you do. If you program for Windows you rely on
it absolutely.
--
Duncan
.
- References:
- copying files
- From: anthony
- A better file copy function (was Re: copying files )
- From: Are you Crazy!
- Re: A better file copy function (was Re: copying files )
- From: Duncan McNiven
- copying files
- Prev by Date: Re: Which Delphi to make good looking XP programs? FIXED
- Next by Date: simple thread
- Previous by thread: Re: A better file copy function (was Re: copying files )
- Next by thread: Re: copying files
- Index(es):
Relevant Pages
|