Thread View: borland.public.cppbuilder.nativeapi
3 messages
3 total messages
Started by Robert G. Hoover
Fri, 02 Mar 2007 03:20
read/write semiphores?
Author: Robert G. Hoover
Date: Fri, 02 Mar 2007 03:20
Date: Fri, 02 Mar 2007 03:20
17 lines
1720 bytes
1720 bytes
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. Thanks! Rob
Re: read/write semiphores?
Author: Remy Lebeau (TeamB)
Date: Fri, 02 Mar 2007 03:09
Date: Fri, 02 Mar 2007 03:09
32 lines
2305 bytes
2305 bytes
"Robert G. Hoover" <not.a.real.address@anywhere.sorry> wrote in message news:45e797e2$1@newsgroups.borland.com... > What's the best way to guard against one program writing > to a file when another program is reading the same file? Open the file with writing access denied to other processes. LoadFromFile() opens the file with writing access denied. If another program already has the file open for writing, LoadFromFile() will fail with an exception thrown. If another program tries to open the file for writing after LoadFromFile() has it open, the other program will fail. SaveToFile() creates the file with exclusive access. If another program already has the file open for any reason, SaveToFile() will fail. If another program tries to open the file for any reason after SaveToFile() has opened the file, the other program will fail. > 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. Then you should re-think your design. Having both programs accessing the same file at the same time is not a good choice. They need to communicate with each other so that they can coordinate their access. Otherwise, you should offload the file access to another dedicated process that they share so that they do not access the file directly. Gambit
Re: read/write semiphores?
Author: 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
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads