Page 1 of 1
How to make sure a file handle is closed
Posted: Fri Oct 15, 2010 2:46 am
by wallgod
I've noticed that sometimes (approximately 4% of the time), when I run a PB app that deals with writing to a file and closing it, Windows will take extra time to release the file handle even though it's technically closed, which causes an access violation if I attempt to immediately access the same target file again. I figure I must need some sort of wait function to verify the handle has been completely released. I am considering adding a simple delay after closing the file, but what's the proper way of handling this sort of thing?
Re: How to make sure a file handle is closed
Posted: Fri Oct 15, 2010 4:00 am
by Mistrel
I'm not following this exactly. Either the file is actively open or it's closed. Would you post an example?
Back on some old Apple computer, if I remember correctly, if you forgot to close a file it would remain "stuck" open until you reboot.

Re: How to make sure a file handle is closed
Posted: Fri Oct 15, 2010 4:20 am
by eesau
How are you accessing the file again? Posting a snippet would help in locating the problem.
Re: How to make sure a file handle is closed
Posted: Fri Oct 15, 2010 4:41 am
by wallgod
It's something like this, but called repeatedly on the same file to replace different pieces.
Code: Select all
#REPLACEONE = 1
#SHOWRESULTS = 2
Procedure.i FileHexReplace(File$, DataToFind$, DataToReplace$, Flags=0, StartPosition=1, BufferLen=4096, *Count=0)
Protected _ltf.i = Len(DataToFind$), _ltr.i=Len(DataToReplace$), length.i = _ltf
length / 2
If (length = 0) Or (StartPosition <= 0) Or (BufferLen <= 0) : ProcedureReturn -1 : EndIf
If (BufferLen < length) Or (Flags < 0) Or (_ltr <> _ltr) : ProcedureReturn -1 : EndIf
Protected *searchdata = AllocateMemory(length * 2 + BufferLen), *replacedata = *searchdata + length, k.i
If *searchdata = 0 : ProcedureReturn -2 : EndIf
For k = 0 To length - 1
PokeB(*searchdata + k, Val("$" + PeekS(@DataToFind$ + k * 2, 2)))
PokeB(*replacedata + k, Val("$" + PeekS(@DataToReplace$ + k * 2, 2)))
Next
If FileSize(File$) >= 0
Protected file = OpenFile(#PB_Any, File$)
If file
Protected readpos = StartPosition - 1, thiseof = Lof(file) - length
While (Not Eof(file)) And (readpos <= thiseof)
FileSeek(file, readpos)
Protected *testdata.c = *replacedata + length, DataRead = ReadData(file, *testdata, BufferLen), result.i, replacecount.i, position.s
For k = 0 To DataRead - length
If CompareMemory(*testdata + k, *searchdata, length)
FileSeek(file, readpos + k)
WriteData(file, *replacedata, length)
result = readpos + k + 1 : replacecount + 1
position = "#" + Str(replacecount) + " {" + Hex(result) + "}"
If (Flags & #SHOWRESULTS) : PrintN(position) : EndIf
If DataRead - length - k <= length : readpos + 2 * length + k - DataRead - 1 : EndIf
k + length - 1
If (Flags & #REPLACEONE) : Break 2 : EndIf
EndIf
Next
readpos + DataRead - length - 1
Wend
CloseFile(file)
Else
result = -3
EndIf
Else
result = -4
EndIf
FreeMemory(*searchdata)
If *Count <> 0 : PokeI(*Count, replacecount) : EndIf
ProcedureReturn result
EndProcedure
result = FileHexReplace("testfile.dat", "0F84F9", "90E9F9", #SHOWRESULTS, 1, 4*1024, @counter)
All credit goes to cas for writing this procedure. I just removed a bit here and there that I didn't need.
The original post can be found here:
http://www.purebasic.fr/english/viewtop ... 6&start=24.