Article View: borland.public.cppbuilder.nativeapi
Article #2427Re: read/write semiphores?
From: Dennis Jones
Date: Fri, 02 Mar 2007 16:33
Date: Fri, 02 Mar 2007 16:33
82 lines
4412 bytes
4412 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote in message
news:45e797e2$1@newsgroups.borland.com...
> Hi,
>
> What's the best way to guard against one program writing to a file when
> another
> program is reading the same file?
>
> In my app, I use TStringList::LoadFromFile() to read in the contents of a
> particular file. I manipulate the contents to my liking and then save the
> file
> back to the disk using TStringList::SaveToFile(). In another app, I also
> read in
> the contents of the same file, append additional contents to it, and then
> save
> the amended file to the disk under the same name. I need to make sure that
> no
> additions are lost because it happens at just the wrong time after my
> first app
> reads the file but before my first app saves the revised file. I'm pretty
> sure I
> can use a marker file, but I was hoping for a more elegant method.
Reading and appending are two separate tasks, and the time between their
invocation is the time during which you don't want to allow reading by your
other app. So, instead of using two separate tasks, you effectively need
one task -- one that will prevent all access to the file beginning at the
time it is opened, and ending only after it has been closed.
Remy suggested that you have the applications communicate with each other to
coordinate access. One way you could do that (as you've already hinted by
your subject line) is to use a named semaphore.
Another way to accomplish the same task without a semaphore would be to let
the file system do the work for you, if you don't mind doing a little
polling. For your read/append process, instead of using TStringList's
ReadFromFile and SaveToFile methods (which is two tasks, separated by some
period of time, during which your other process could lock the file), use a
TFileStream to open and close the file with the appropriate access, and do
your reading and appending with the TFileStream:
1) Open the file with exclusive access (TFileStream *fs = new TFileStream(
filename, fmOpenReadWrite | fmShareExclusive ) )
1a) If the file cannot be opened, the reading process is using it (see
blow). Sleep for a short time (50ms?) and try again until access is
granted.
2) Read the file into the stream (TFileStream::ReadBuffer())
3) Load your stringlist from the stream (TStringList::LoadFromStream())
4) Manipulate your stringlist as necessary
5) Write the stringlist back to the stream (TStringList::SaveToStream())
6) Save the file back to disk (TFileStream::WriteBuffer())
7) Close the file (delete fs)
Then, in your reading process, try to open the file. If it fails to open
(an exception will be thrown), sleep for a short time (say 50ms), then try
again, repeating until the file can be opened (the following snippet is
copied from one of my apps):
while ( true )
{
try
{
pFileStream.reset( new TFileStream( FileName, fmOpenRead |
fmShareExclusive ) );
// if the file can be opened for exclusive access, the writer has
// finished writing to it and closed it; break out of the while
loop
// and allow processing to begin
break;
}
catch(...)
{
// exception will be thrown if the file could not be opened for
// exclusive access; wait a bit and try again
::Sleep( 50 );
}
}
Hope this helps.
- Dennis
Technical Details
Message-ID:
<45e851b4$1@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<45e797e2$1@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,425c3313c9d5dcd8 X-Google-Attributes: gid10cc67,public X-Google-Language: ENGLISH,ASCII-7-bit From: "Dennis Jones" <nospam@nospam.com> Newsgroups: borland.public.cppbuilder.nativeapi References: <45e797e2$1@newsgroups.borland.com> Subject: Re: read/write semiphores? Date: Fri, 2 Mar 2007 08:33:06 -0800 Lines: 84 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.3028 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3028 X-RFC2646: Format=Flowed; Original NNTP-Posting-Host: 71.245.109.58 Message-ID: <45e851b4$1@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1172853172 71.245.109.58 (2 Mar 2007 08:32:52 -0800) Path: arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail