Tfilestream: file in use

hi,

under D3 and WIN98:
i open a file with Tfilestream.create share-exclusive.
if the file is not open, it works well.
if the file is in use by another app then i got the message
"file ... could not be opened".
this is ok.
But i do not want the message on the screen, i want a
message-code in my app for waiting until the file is no longer in use.

How can i get the message-code ?
is there a special compiler-switch like {I-} ?
getlasterror does not work. why ?

   setlasterror(0);
   fs:=tfilestream.create(filename,fmopenreadwrite or fmshareexclusive);
   jf:=getlasterror;

>>>jf is always 0, even if the file is in use. <<<


thanks
titz

LVL 1
titzAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kretzschmarCommented:
hmm,

just a suggestion

var isOpened : Boolean;
begin
  IsOpened := false;
  while Not IsOpened do
  begin
    Try
      fs := ...
      IsOpened := True;
    except
      //
    end;
  end;
end;  

meikl ;-)
0
simonetCommented:
Here's the IsFileInUse function:

http://www.bhnet.com.br/~simonet/tipstricks/fileinuse.htm

Yours,

Alex
0
LischkeCommented:
Here is again my recommendation not to use TFileStream but go down to API level or at least to SysUtils.FileOpen (which actually wrapps the API). It will not raise an exception but return a value > 0 if the file could be open. This way GetLastError should also work.

Ciao, Mike
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

sburckCommented:
This trick gives you a lot of information on the file, with one drawback.  If you do a FindFirst on your filename, and the file exists, you will know about it.  Then, if you check the size of the file, and find that it is 0, there is one of two possibilities.  (1)  Somebody made an empty file (it does happen, and this is the drawback) or (2) it is in use.  You can eliminate the drawback by trying to delete the empty file - success means that there really was an empty file of that name.  The only problem here is if somebody really wanted an empty file of that name.

This technique is a bit sideways, though, and I mention it mostly as a curiosity, as it uses a side effect of the way windows (dos) works now, and not necessarily a clean solution for the future.
0
mhervaisCommented:
mike fileopen does not raise an exception, but it does not give a clear info weather the file is in use or not.

Maybe Titz should have a try with simonet's algorithm ...

regards, marc
0
titzAuthor Commented:
hi mike,

have you had bad experiences with Tfilestream ?
why are you against these ? i do not know.

cheers

titz

0
titzAuthor Commented:
hi,

the "simonet-solution" uses "createfile".
i would have used this function in my project but
i found no equivalents for the "seek"-function
(=positioning the file-pointer) and the
"size"-function (=size of the file in bytes), which are
available in Tfilestream.
i found nothing in the HELP, therefore i thought
that such functions do not exist in API32.

am i wrong ?

cheers
titz
0
LischkeCommented:
Sometimes I have the feeling I'm talking to a wall. Marc, what do you think does FileOpen use? Look into the sources, it's CreateFile!

Titz, can you please clarify what we are now talking about? Until now I thought you wanna know if a file is in use, nothing else. What do you want with Seek, Size etc.? This has nothing to do with your original question.

There are of course such functions at API level (how can TFileStream else work?). These are GetFileSize and SetFilePointer.

It seems to me you wanna use the file after the check for something else so I'd recommend a two step approach. First check whether the file is in use by using CreateFile, FileOpen or Alex's solution. If this went fine then open the file with a file stream to actually access it.

Ciao, Mike

PS: I don't have anything against TFileStream. I use it myself very frequntly, but sometimes the VCL tries to hide too much from the programmer, does not supply special features (like overlapped I/O) or does other unwanted things (like raising an excpetion). What I encourage is not only to rely on the VCL but to learn how it interacts with Windows.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
KECommented:
1. How can i get the message-code ?
try
  fs := TFileStream.Create( blablabla );
except
  On E: Exception do
    HeresTheMessage := E.Message;
end;
I don't remember wether the errorcode goes along.
 
2. is there a special compiler-switch like {I-} ?
NOPE !

3. getlasterror does not work. why ?
Because TFileStream has "used it" when it raised the exception and your thread has called other WinApi's after the error occured - you can't change this behaviour, as it is built in to the TFileStream !
 

Try this instead:

Open the file with CreateFile and check that the handle is not invalid - if it is you can call GetLastError to get the reason. If it's valid, use a THandleStream with the obtained handle - remember to close the handle when you are done !

Sorry, if there's echo's in this comment...

Regards
0
titzAuthor Commented:
hi mike,

here is the solution for your question:
i do not want to irritate someone, but i had some problems
with file-handling: "opening", "reading", "in use" in a network.
i split those problems into small parts (=single questions).
i tried some answers of these questions:  
they created new solutions and new problems.
therefore i had to decide how to go on and sometimes
i took a new direction. ok ?

for the history : i started with the API-function
"createfile" but had some difficulties because i
did not found the API-functions you now mentioned:
"getfilesize" and "setfilepointer". so i turned to Tfilestream.
they do what i want and i will turn back to my first
project-solution using "createfile".

perhaps it sounds a little bit strange,
but this was my way.

many thanks and have a nice weekend !
titz

(the points will be yours)
0
titzAuthor Commented:
hi alex,
for your solution you shall have some points too.
i will install a question for you.

thanks
titz
0
mhervaisCommented:
lishke sorry about that. I Have been looking Powerbuilder a lot and they had fileopen as well for low level file opening function.

so I got convinced that PB and Delphi was directly mapped onto windows SDK, and that they worked the same way.

for Howether, I think that since it is being rewritten in Delphi, this function could not be called a low level one.

regards, Marc
0
LischkeCommented:
Well, that's the burden of being a Delphi programmer. Most of the time we have to deal with functions wrapped by at least one additional layer in the VCL. Now that this problem has been solved we can happily go now into weekend.

Titz, I understand your way. It's the same old story all the time for all of us, isn't it :-)?

Thank you and

Ciao, Mike
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.