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.