stickleprojects Level: Moderator

 Registered: 09-09-2002 Posts: 997
|
Re: Gracefully Handling Multiple Users Accessing the Same File Simultaneously
Hi,
You should use openfile, then capture the error gracefully.
To maximise the number of users that can use a file, get a local copy of it (either in memory or on disk).
If you need to support concurrent updates of the file consider using a database -it's free.
You should open the file, read it, then close it.
for example (assuming the file already exists):
on error resume next
Set tst = fle.OpenTextFile(strFileName, ForReading, False)
if err=0 then
mybuffer = tst.readall
blnAllRead = true
else
mybuffer = ""
blnAllRead = false
end if
tst.Close
Set tst = Nothing
( |
The method you have will work, however, there is a (small) time delay between "Isreadytoopen" and reading the file, so do it all in one go.
If you need to allow updative access (ie. "lock" the file whilst someone is "updating" it), you could use this class. Paste it into a class module:
Option Explicit
Private m_LockFileHandle As Integer
Public Enum LockFileResultEnum
Ok = -1
Failed = 0
LockFileInUse
UnableToSetLockFileName
End Enum
Private m_strLockFileName As String
Private m_strLockFileContents As String
Public Property Get LockFileContents() As String
LockFileContents = m_strLockFileContents
End Property
Private Function SetLockFileName(strFilename As String) As Boolean
m_strLockFileName = strFilename & ".lck"
SetLockFileName = True
End Function
Private Function LockFileExists() As Boolean
If Dir$(m_strLockFileName) <> "" Then LockFileExists = True
End Function
Private Function DeleteLockFile() As Boolean
If LockFileExists() Then
On Error Resume Next
Kill m_strLockFileName
If LockFileExists() = False Then DeleteLockFile = True
Else
DeleteLockFile = True
End If
End Function
Public Function LockFile(strFilename As String, Optional strLockText As String) As LockFileResultEnum
Dim lngRet As LockFileResultEnum
On Error GoTo errh
If m_LockFileHandle <> -1 Then
Err.Raise -1, "LockFile", "Lock already in use, use ReleaseLock to release lock"
GoTo exith
End If
If SetLockFileName() Then
' Kill the file - it may be there if the client crashed
If DeleteLockFile() = False Then
' Read the locking info
Dim fin As Integer
fin = FreeFile
Open m_LockFileName For Input As fin
m_strLockTextFound = Input(LOF(fin), fin)
Close fin
lngRet = LockFileInUse
Else
' Lock file doesn't exist, so let's create one AND KEEP IT OPEN!!!
m_LockFileHandle = FreeFile
Open m_LockFileName For Output As fout
Print #m_LockFileHandle, strLockText
lngRet = Ok
End If
Else
lngRet = UnableToSetLockFileName
End If
LockFile = lngRet
exith:
On Error GoTo 0
Exit Function
errh:
Screen.MousePointer = vbDefault
Err.Raise Err.Number, Err.Source & ",Project1.clsMyFileLock.LockFile", Err.Description
End Function
Public Sub ReleaseLock()
On Error Resume Next
If m_LockFileHandle <> 0 Then Close m_LockFileHandle
If Err = 0 Then
m_LockFileHandle = -1
m_strLockFileContents = ""
m_strLockFileName = ""
End If
End Sub
Private Sub Class_Initialize()
m_LockFileHandle = -1
m_strLockFileContents = ""
m_strLockFileName = ""
End Sub
Private Sub Class_Terminate()
' Release the lock
ReleaseLock
End Sub
|
The class will release the lock when it is destroyed.
The reason why I hold the file handle, is so that the operating system implements the locking and stops someone else zapping the file.
to use:
create an instance of this class for the duration of the lock
then call LockFile(strfilename,"some text here") and check the return value.
If the lock fails (ie. doesn't = True) then you can check the lockfilecontents to see what was in the lockfile
I use the lockfile to hold the user's name, what they were doing, all that sort of thing (incidentally, I write an xml fragment so I can hold lots more info).
this class is limited to one person, but you could extend it to allow read-access but single writeaccess (see msaccess ldb file)
Hope this helps,
Kieron
[Edited by stickleprojects on 06-02-2008 at 08:22 AM GMT]
____________________________
Build it better, faster, quicker, easier.. then fix it (non-offical MS mission statement)
|