asgarcymed Posted December 10, 2007 Posted December 10, 2007 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...
weaponx Posted December 10, 2007 Posted December 10, 2007 (edited) 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 December 10, 2007 by weaponx
zfisherdrums Posted December 10, 2007 Posted December 10, 2007 (edited) 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 December 10, 2007 by zfisherdrums Identify .NET controls by their design time namesLazyReader© could have read all this for you. Unit Testing for AutoItFolder WatcherWord Doc ComparisonThis here blog...
asgarcymed Posted December 10, 2007 Author Posted December 10, 2007 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: expandcollapse popup$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...
zfisherdrums Posted December 10, 2007 Posted December 10, 2007 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... Identify .NET controls by their design time namesLazyReader© could have read all this for you. Unit Testing for AutoItFolder WatcherWord Doc ComparisonThis here blog...
PsaltyDS Posted December 10, 2007 Posted December 10, 2007 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): expandcollapse popup$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
asgarcymed Posted December 11, 2007 Author Posted December 11, 2007 PsaltyDS - thank you very much!!!!!!!!!!!!! You solved my problem and I learned with it!!! MLMK - my blogging craziness...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now