Jump to content

Handle of a handle produces weird behavior


 Share

Recommended Posts

There was a topic about using already opened file handles with _FileReadToArray().

Remembering a minor change made some time ago to allow using a handle with _FileWriteFromArray(), I made a bad assumption and replied that you could use it with _FileReadToArray() also, which was the wrong answer. But in the process of checking my answer and realizing it was wrong I stumbled across another strange behavior that came about by passing a handle to FileOpen() instead of a string. I seem to have a permanently open handle to data in memory from a file that doesn't even exist any more. I don't really understand it yet.

This is how I got there:

When I gave the incorrect answer about _FileReadToArray() using handles, I posted an example (that worked, by the way):

#include <File.au3>
#include <Array.au3>

Global $sFile = "C:\Temp\Test\Test.txt", $hFile, $avFile, $RET

; Read file with handle
$hFile = FileOpen($sFile)
If $hFile = -1 Then
    MsgBox(16, "Error", "Error opening file for read.")
    Exit
EndIf
$RET = _FileReadToArray($hFile, $avFile)
FileClose($hFile)
_ArrayDisplay($avFile, "$RET = " & $RET)

The array displays the correct contents of Test.txt file.

After posting that, I saw that Jos had already posted the opposite (and correct) answer that handles should not be passed to _FileReadToArray().

That made me wonder why my example worked, so I looked in the File.au3 UDF at the function and found it unconditionally does a FileOpen() with the file path, not checking if it is a handle already. That means when I passed a handle to it, something resembling this functionally happened:

Global $sFile = "C:\Temp\Test\Test.txt", $hFile1, $hFile2, $avFile, $RET

; Read file with handle
$hFile1 = FileOpen($sFile, 0)
If $hFile1 = -1 Then
    MsgBox(16, "Error", "Error opening file for read.")
    Exit
EndIf

$hFile2 = FileOpen($hFile1, 0)
$sTemp = FileRead($hFile2)
FileClose($hFile2)
FileClose($hFile1)

ConsoleWrite("$sTemp = " & $sTemp & @LF)

And it returned the correct contents of the file at the time.

Since then, that Test.txt file has been deleted, recreated, overwritten in mode=32 Unicode with different text -- all yesterday. I have since logged off of the computer, and logged back in again today.

As I post this today, when I run the above code, the original unmodified contents of the file are still returned!

There is a ghostly file handle in the system that still points to a memory structure that still contains that data. I can get the actual current contents of the file, or the ghost contents from the same script by using either a normal handle reference or the funky double reference:

Global $sFile = "C:\Temp\Test\Test.txt", $hFile1, $hFile2, $avFile, $RET

; Read file with single handle
$hFile1 = FileOpen($sFile, 0)
If $hFile1 = -1 Then
    MsgBox(16, "Error", "Error opening file for read.")
    Exit
EndIf
$sTemp = FileRead($hFile1)
FileClose($hFile1)
ConsoleWrite("$sTemp = " & $sTemp & @LF)

; Read file with "double" handle
$hFile1 = FileOpen($sFile, 0)
If $hFile1 = -1 Then
    MsgBox(16, "Error", "Error opening file for read.")
    Exit
EndIf
$hFile2 = FileOpen($hFile1, 0)
$sTemp = FileRead($hFile2)
FileClose($hFile2)
FileClose($hFile1)
ConsoleWrite("$sTemp = " & $sTemp & @LF)

If I change $sFile to some other file, like "C:\Temp\Test\NewText.txt", I still get the correct current contents of the correct file with a normal single handle reference, and the "ghost" contents of the old file with the double reference. So, if I pass the normal handle to ANY file as an input to FileOpen() I get the "ghost" handle back that still refers to the old file data, which is still in memory even if the original file doesn't exist anymore.

I haven't tried a reboot yet to see if it clears the condition, but I will after posting this...

:P

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

After reboot: SAME RESULTS!

I wouldn't have called that. I can see that the old data block might be floating around in RAM somewhere, but I can still get a reliable reference to it, and that is strange!

The original file, long since overwritten and deleted multiple times, contained "one" through "nine". The current file contains "one" through "five" repeated three times (testing _FileWriteFromArray() in a loop at the time). This is the result running the demo script above, after a reboot:

>"C:\Progra~1\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\temp\Test\Test1.au3" /autoit3dir "C:\Program Files\AutoIt3" /UserParams  
+>10:13:35 Starting AutoIt3Wrapper v.1.10.1.12  Environment(Language:0409  Keyboard:00000409  OS:WIN_XP/Service Pack 2  CPU:X86  ANSI)
>Running AU3Check (1.54.13.0)  from:C:\Program Files\AutoIt3
+>10:13:35 AU3Check ended.rc:0
>Running:(3.2.12.1):C:\Program Files\AutoIt3\autoit3.exe "C:\temp\Test\Test1.au3"   
$sTemp = one
two
three
four
five
one
two
three
four
five
one
two
three
four
five

$sTemp = One
Two
Three
Four
Five
Six
Seven
Eight
Nine
+>10:13:35 AutoIT3.exe ended.rc:0
+>10:13:37 AutoIt3Wrapper Finished
>Exit code: 0   Time: 1.938

Next test will be a power-down cold boot, which has got to clear volatile RAM...

:P

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

OK, now it's getting eerie, in a Ghost In The Shell kind of way... I did a shutdown/powerup - still there. Did a shutdown/disconnect power for 10sec/powerup - still there.

Where is this data still coming from?! I've got to be missing something stupid and basic now.

:P

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I've got to be missing something stupid and basic now.

Yep... that was it. DaveF pointed out that because FileOpen() is expecting a string, it will convert whatever you give it into a string. In this case, the file handle becomes "1" as a string, and it opens a file called "1", which at some point in all the variations I tried of this code, got the "one" thru "nine" text written to it. So, every time I performed the "double handle" trick, I was reading the file "1".

Thank you to DaveF for restoring my sanity.

:P

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...