Jump to content

Trying to add each line of a text file to Dictionary Object


Recommended Posts

I have a text file which contains many lines (no duplicate lines); and I am trying to add each line to the Dictionary Object. I cannot understand what is going wrong, but when EOF (End-of-File) is reached, I get an error message:

"The requested action with this object has failed"

My script is:

$txt_file = @DesktopDir & "\Text-Lines.txt" 

$open_file = FileOpen($txt_file, 0)

$obj_dict = ObjCreate("Scripting.Dictionary")
$obj_dict.CompareMode = 1 ; "Text Mode"


$x = 0
While 1
    If @error = -1 Then ExitLoop
    $line = FileReadLine($open_file)
    $dict_key = $line
    $x = $x + 1

    If IsObj($obj_dict) Then
        $obj_dict.Add ($dict_key, $x)
        If @error Then
            ExitLoop
        EndIf
    Else
        ExitLoop
    EndIf

    
    TrayTip("Line " & $x, $dict_key, 1)
    
WEnd

Can you please help me to correct/debug this script?

Thanks in advance.

Best regards.

MLMK - my blogging craziness...
Link to comment
Share on other sites

Maybe just use FileReadToArray and loop through the array.

#Include <file.au3>

$txt_file = @DesktopDir & "\Text-Lines.txt"

Dim $file_array

_FileReadToArray($txt_file, $file_array)

$obj_dict = ObjCreate("Scripting.Dictionary")
$obj_dict.CompareMode = 1 ; "Text Mode"

For $X = 1 to $file_array[0]
     $obj_dict.Add ($file_array[$X], $x)
Next
Edited by weaponx
Link to comment
Share on other sites

Hello asgarcymed,

I agree with WeaponX and his solution. There are many ways to skin this cat.

Below is a "working" version of your script. It appears that the script is populating a dictionary where the lines of text are the keys and the associated values are incremental. Is that your intent?

Also, kudos for checking for errors. Moving the error check after FileReadLine cause the looped to be exited correctly. However, since $obj_dct is an object, it does not register its error with the @error macro. Instead, it should barf a COM error.

$txt_file = @DesktopDir & "\Text-Lines.txt"
$open_file = FileOpen($txt_file, 0)
$obj_dict = ObjCreate("Scripting.Dictionary")
If IsObj($obj_dict) Then
    $obj_dict.CompareMode = 1; "Text Mode"
Else
    exit 1
EndIf

$x = 0
While 1 
    $line = FileReadLine($open_file)
    If @error = -1 Then ExitLoop
    $x = $x + 1
    $obj_dict.Add ($line, $x) 
WEnd
Edited by zfisherdrums
Link to comment
Share on other sites

Obviously, this problem/script makes no sense when considered alone, "per se".

I felt this problem when I was trying to make a much more complex script, like this:

A text file contains one md5 hash/checksum per line (corresponding to one file; this text file was previously made, and in the present moment I do not have direct access to such files, only to their md5 hash/checksum, stored in the text file)

=>

the script reads such text file and each line (md5 hash/checksum) is added, as key, to the dictionary object

=> => Next step:

Look at a specified directory (now I have direct access to this directory and its files)

=>

for each file, one-by-one, get md5 hash/checksum (using an ActiveX=COM object)

=>

If a repeated md5 is found (means duplicate file) then delete file [the dictionary's "Exists" method checks and does not allow 2 keys to be equal. Thus, if a duplicate file exists, the keys (md5) would be equal...)

Here it is my full script:

$path = "C:\test" 

$txt_file = @DesktopDir & "\MD5.txt" 

$obj_md5 = ObjCreate("XStandard.MD5") ; ActiveX MD5 Hash/CheckSum


$open_file = FileOpen($txt_file, 0)

$obj_dict = ObjCreate("Scripting.Dictionary")

If IsObj($obj_dict) Then
    $obj_dict.CompareMode = 1; "Text Mode"
Else
    Exit 1
EndIf


$x = 0
While 1
    If @error = -1 Then ExitLoop
    $line = FileReadLine($open_file)
    $dict_key = $line
    $x = $x + 1
    $obj_dict.Add ($dict_key, $x)
WEnd


$search = FileFindFirstFile($path & "\*.*")
$y = 0
While $search = 1
    If @error Then ExitLoop
    
    $file = FileFindNextFile($search)

    $md5_hash = $obj_md5.GetCheckSumFromFile ($file)

    $dict_key2 = $md5_hash
    
    $y = $y + 1
    
    If $obj_dict.Exists ($dict_key2) Then
        FileRecycle($file)
    Else
        $obj_dict.Add ($dict_key2, $y)
        FileWrite($txt_file, $dict_key2 & Chr(13)) ; Update MD5.txt File => New File (not duplicated)
    EndIf

WEnd

However this script does not work and alone, with no help, I cannot make it work...

Can you help me?

PS - WeaponX - I tried: Read Line to Array => Add to Dictionary [the problem is that such text file contains 10000 lines, what exceeds the array size in AutoIt... Unlike this, Object Dictionary has no limits of elements number...]

Thanks in advance.

Regards.

MLMK - my blogging craziness...
Link to comment
Share on other sites

Funny, I wrote this exact same solution except it was in C#. I have to leave for awhile, but I'll take a look at it and see what I can find. Knowing this forum, someone will have an answer for you shortly. :)

Zach...

Link to comment
Share on other sites

AutoIt's limit for arrays is 16 million elements. Your 10,000 line file is not scaring AutoIt. However the .Exists method may be faster than walking an array in a For/Next loop every time, so it still might be the right choice for this.

Your basic problem is the While loop is never true because the return from FileFindFirstFile() is a search handle, NOT a 1. You also have a weird tendency to test the @error before performing the function.

Try it this way (the ConsoleWrite's can be removed when you get a good test):

$path = "C:\test"
$txt_file = @DesktopDir & "\MD5.txt"

$obj_md5 = ObjCreate("XStandard.MD5") ; ActiveX MD5 Hash/CheckSum
If IsObj($obj_md5) Then
    ConsoleWrite("Debug: $obj_md5 = " & ObjName($obj_md5) & @LF)
Else
    MsgBox(16, "Error", "XStandard.MD5 COM interface not available")
    Exit 1
EndIf

$obj_dict = ObjCreate("Scripting.Dictionary")
If IsObj($obj_dict) Then
    ConsoleWrite("Debug: $obj_dict = " & ObjName($obj_dict) & @LF)
    $obj_dict.CompareMode = 1; "Text Mode"
Else
    MsgBox(16, "Error", "Error creating scripting dictionary")
    Exit 1
EndIf

$open_file = FileOpen($txt_file, 0) ; 0= read
$x = 0
While 1
    $dict_key = FileReadLine($open_file)
    If @error = -1 Then ExitLoop
    $x += 1
    ConsoleWrite("Debug: Adding to dictionary: " & $dict_key & " = " & $x & @LF)
    $obj_dict.Add($dict_key, $x)
WEnd
FileClose($open_file)

$open_file = FileOpen($txt_file, 1) ; 1 = append
$search = FileFindFirstFile($path & "\*.*")
While 1
    $file = $path & "\" & FileFindNextFile($search)
    If @error Then ExitLoop
    $md5_hash = $obj_md5.GetCheckSumFromFile($file)
    If $obj_dict.Exists($md5_hash) Then
        ConsoleWrite("Debug: Moving to recycle bin: " & $file & @LF)
        FileRecycle($file)
    Else
        ConsoleWrite("Debug: Adding MD5 hash for: " & $file & @LF)
        $x += 1
        ConsoleWrite("Debug: Adding to dictionary: " & $md5_hash & " = " & $x & @LF)
        $obj_dict.Add($md5_hash, $x)
        FileWrite($open_file, $md5_hash & Chr(13))
    EndIf
WEnd

FileClose($open_file)
FileClose($search)

:)

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...