Jump to content



Photo

Filename exists auto rename making too many duplicates


  • Please log in to reply
9 replies to this topic

#1 nivtop

nivtop

    Seeker

  • Active Members
  • 10 posts

Posted 17 February 2011 - 07:45 PM

Hello all

I'm new to autoit scripting so please bare with me...

this is my Search function which searches local drives for .PST files and if any are found they are copied to /My Documents/PST/ directory although I had some issues with PST files that are the same filename so I needed to implement some auto rename & add '1' to end of filename.. this kinda works but sometimes it makes too many copies of the same .PST files when auto-renaming

For example, theres 2 archive.pst files with same filename so its suppose to rename only one file to archive(1).pst and thats it..although its making more duplicates: archive(1).pst, archive(1)(1).pst, archive(1)(1)(1).pst..

maybe someone can help me clean it up and work properly

Plain Text         
Func Search($current)     Local $search = FileFindFirstFile($current & "\*.*")     While 1     Dim $file = FileFindNextFile($search)     If @error Or StringLen($file) < 1 Then ExitLoop ;Add pst / pab files to the array and backup If Not StringInStr(FileGetAttrib($current & "\" & $file), "D") and Not StringInStr($current & "\" & $file, $pstdest) And ($file <> "." Or $file <> "..") And StringRight($file, 3) = "pst" or StringRight($file, 3) = "pab" Then $filexists = $pstdest & $file If FileExists ($filexists) Then     $position = StringInStr($filexists, '.', 0, -1)     $filename = StringLeft($filexists, $position -1)     $extension = StringMid($filexists, $position)     For $i = 1 To 1000000         $newfilename = $filename & "(" & $i & ")" & $extension         If FileCopy($filexists, $newfilename) Then ExitLoop     Next      MsgBox(4096,"PST FILENAME DUPLICATE", "Original PST: " & $filexists & "   New PST Filename: " & $newfilename, 10) $result = 3 ;dont ask Else $result = FileCopyP($current & "\" & $file, $pstdest) EndIf ;Write to log file. If $result = 1 Then _FileWriteLog($backupdest&"\" & "pstlog.log", "BACKUP SUCCESS: " & $current & "\" & $file) ElseIf $result = 3 Then _FileWriteLog($backupdest&"\" & "pstlog.log", "**RENAME** BACKUP SUCCESS: " & $current & "\" & $file & "  RENAMED TO: " & $newfilename) Else    _FileWriteLog($backupdest&"\" & "pstlog.log", "**FAIL** BACKUP FAILURE: " & $current & "\" & $file) Endif EndIf If StringInStr(FileGetAttrib($current & "\" & $file), "D") And ($file <> "." Or $file <> "..") AND StringInStr($current & "\" & $file, $pstdest) = 0 Then     Search($current & "\" & $file) EndIf WEnd FileClose($search) EndFunc








#2 MrMitchell

MrMitchell

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 747 posts

Posted 17 February 2011 - 07:55 PM

Suggested alternative: You could use something unique instead of (1), (2),... or whatever it is you have going on. Rename the file to something that is unique and maybe more meaningful, like archive_mmddyyhhmm.pst or instead of the current date use one of the dates of that particular file like last modified date/time.

#3 willichan

willichan

    Old Geek

  • Active Members
  • PipPipPipPipPipPip
  • 417 posts

Posted 17 February 2011 - 08:56 PM

Perhaps, instead of just comparing names, you should check to see if they really are duplicates of each other or not. That way, when you re-run your utility, everything won't just get duplicated again, and you can focus on unique files.

AutoIt         
Func _FileIsDuplicate($file1, $file2)     Local Const $BlockSize = 16384 ;(16K) Work with smaller blocks at a time to avoid gobbling memory     Local $f1, $f2 ;file handles     Local $d1, $d2 ;data holders     Local $ismatch = True ;assume they match until a difference is found     ;make sure files exist, or return false     If (Not FileExists($file1)) Or (Not FileExists($file2)) Then Return False     ;make sure files can be openned for reading, or return false     $f1 = FileOpen($file1, 0)     If $f1 = -1 Then Return False     $f2 = FileOpen($file2, 0)     If $f2 = -1 Then         FileClose($f1) ;don't forget to close the other file handle         Return False     EndIf     While 1         $d1 = FileRead($f1, $BlockSize)         If @error = -1 Then ;end of file1             $d2 = FileRead($f2, $BlockSize)             If @error <> -1 Then $ismatch = False ;but not end of file2             ExitLoop         EndIf         $d2 = FileRead($f2, $BlockSize)         If (@error = -1) Or ($d1 <> $d2) Then ;not end of file1, but end of file2 -or- blocks don't match             $ismatch = False             ExitLoop         EndIf     WEnd     ;be sure to close the file handles     FileClose($f2)     FileClose($f1)     ;retirm the result     Return $ismatch EndFunc


#4 guinness

guinness

    guinness

  • MVPs
  • 11,067 posts

Posted 17 February 2011 - 09:03 PM

Another way without using File Handles and FileClose ...
Function:
AutoIt         
; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 ; #FUNCTION# ========================================================================================================= ; Name...........: _FileCompareContents() ; Description ...: Checks the data content between two files. ; Syntax.........: _FileCompareContents($sSource, $sDestination, [$iWhitespace = 0]) ; Parameters ....: $sSource - A valid file path. ;                  $sDestination - A valid file path. ;                  $iWhitespace - Remove whitespace, 0 = Don't remove whitespace, 1 = Remove whitespace. ; Requirement(s).: v3.2.12.1 or higher ; Return values .: Success - True ;                  Failure - False ; Author ........: guinness ; Example........; Yes ;===================================================================================================================== Func _FileCompareContents($sSource, $sDestination, $iWhitespace = 0)     If (FileExists($sSource) And FileExists($sDestination)) = 0 Then         Return SetError(1, 0, 0)     EndIf     If $iWhitespace Then         Return StringStripWS(FileRead($sSource), 8) = StringStripWS(FileRead($sDestination), 8)     EndIf     Return FileRead($sSource) = FileRead($sDestination) EndFunc   ;==>_FileCompareContents

Example use of Function:
AutoIt         
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 Global $aArray[3] = [2] For $A = 1 To $aArray[0]     $aArray[$A] = FileOpenDialog("_FileCompareContents()", @ScriptDir, "All (*.*)")     If @error Then         Exit     EndIf Next MsgBox(64, "_FileCompareContents()", _FileCompareContents($aArray[1], $aArray[2])) ; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 ; #FUNCTION# ========================================================================================================= ; Name...........: _FileCompareContents() ; Description ...: Checks the data content between two files. ; Syntax.........: _FileCompareContents($sSource, $sDestination, [$iWhitespace = 0]) ; Parameters ....: $sSource - A valid file path. ;                  $sDestination - A valid file path. ;                  $iWhitespace - Remove whitespace, 0 = Don't remove whitespace, 1 = Remove whitespace. ; Requirement(s).: v3.2.12.1 or higher ; Return values .: Success - True ;                  Failure - False ; Author ........: guinness ; Example........; Yes ;===================================================================================================================== Func _FileCompareContents($sSource, $sDestination, $iWhitespace = 0)     If (FileExists($sSource) And FileExists($sDestination)) = 0 Then         Return SetError(1, 0, 0)     EndIf     If $iWhitespace Then         Return StringStripWS(FileRead($sSource), 8) = StringStripWS(FileRead($sDestination), 8)     EndIf     Return FileRead($sSource) = FileRead($sDestination) EndFunc   ;==>_FileCompareContents

And check out _FileCompare() as well.

Edited by guinness, 17 May 2011 - 07:21 PM.

Example List: _AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_DesktopDimensions()_DisplayPassword()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUISetIcon()_Icon_Clear()/_Icon_Set()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringIsValid()_StringReplaceWholeWord()_StringStripChar()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()AutoIt SearchAutoIt3 PortableAutoItWinGetTitle()/AutoItWinSetTitle()CodingFileInstallrGeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIGetBkColor()LockFile()PasteBinSciTE JumpSignature CreatorWM_COPYDATAMore Examples...Updated: 11/04/2013


#5 willichan

willichan

    Old Geek

  • Active Members
  • PipPipPipPipPipPip
  • 417 posts

Posted 17 February 2011 - 09:28 PM

And another way without using File Handles and FileClose ...

Interesting approach. I don't think it compares anything past the first $fc_BlockSize characters though.
I don't think the white-space stripping will work for all cases either. if you have white-space that pushes data into the next block in one file, but not in the other, your block compare will not match, even if the overall file data would match without the white-space.

I think your approach will require reading the whole file to work correctly, rather than working with blocks.
Your method should be the faster one, as long as you are working with smaller files, or are not worried about memory.

#6 guinness

guinness

    guinness

  • MVPs
  • 11,067 posts

Posted 17 February 2011 - 09:37 PM

You make a valid point actually! I basically modified the Function below with your little tweak without thinking first :)

Function:
AutoIt         
#include <Constants.au3> MsgBox($MB_SYSTEMMODAL, '', _FileCompareContents(@ScriptFullPath, @ScriptFullPath)) ; #FUNCTION# ==================================================================================================================== ; Name ..........: _FileCompareContents ; Description ...: Checks the data content between two files. ; Syntax ........: _FileCompareContents($sSource, $sDestination[, $fWhitespace = False]) ; Parameters ....: $sSource             - A valid filepath. ;                  $sDestination        - A valid filepath. ;                  $fWhitespace         - [optional] Remove whitespace - True or don't remove whitespace - False. Default is False. ; Return values .: Success - True (file the same) ;                  Failure - False and sets @error to non-zero. (file not the same) ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _FileCompareContents($sSource, $sDestination, $fWhitespace = False)     If FileExists($sSource) = 0 Or FileExists($sDestination) = 0 Then         Return SetError(1, 0, False)     EndIf     $sSource = FileRead($sSource)     $sDestination = FileRead($sDestination)     If $fWhitespace Then         $sSource = StringStripWS($sSource, $STR_STRIPALL)         $sDestination = StringStripWS(FileRead($sDestination), $STR_STRIPALL)     EndIf     Return $sSource == $sDestination EndFunc   ;==>_FileCompareContents

Edited by guinness, 03 June 2013 - 01:02 PM.

Example List: _AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_DesktopDimensions()_DisplayPassword()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUISetIcon()_Icon_Clear()/_Icon_Set()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringIsValid()_StringReplaceWholeWord()_StringStripChar()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()AutoIt SearchAutoIt3 PortableAutoItWinGetTitle()/AutoItWinSetTitle()CodingFileInstallrGeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIGetBkColor()LockFile()PasteBinSciTE JumpSignature CreatorWM_COPYDATAMore Examples...Updated: 11/04/2013


#7 KaFu

KaFu

    Hey, it's just me, KhaFoo...

  • MVPs
  • 3,194 posts

Posted 17 February 2011 - 10:13 PM

I use a function like this in SMF:

$sFilename = @ScriptFullPath $sFilename_Buffer = $sFilename $i = 1 While FileExists($sFilename)     If $i = 1 Then         $sFilename = StringLeft($sFilename_Buffer, StringInStr($sFilename_Buffer, "\", 0, -1)) & "Copy of " & StringRight($sFilename_Buffer, StringLen($sFilename_Buffer) - StringInStr($sFilename_Buffer, "\", 0, -1))     Else         $sFilename = StringLeft($sFilename_Buffer, StringInStr($sFilename_Buffer, "\", 0, -1)) & "Copy of (" & $i & ") " & StringRight($sFilename_Buffer, StringLen($sFilename_Buffer) - StringInStr($sFilename_Buffer, "\", 0, -1))     EndIf     $i += 1 WEnd MsgBox(0,"",$sFilename)


#8 nivtop

nivtop

    Seeker

  • Active Members
  • 10 posts

Posted 18 February 2011 - 02:20 AM

Thx everyone for the input

helped me out

#9 nivtop

nivtop

    Seeker

  • Active Members
  • 10 posts

Posted 18 February 2011 - 03:26 AM

Would anyone know how to make my search function search for *.pst files faster and more efficient?

Thx

#10 Xenobiologist

Xenobiologist

    Xx Code~Mega xX

  • MVPs
  • 4,760 posts

Posted 18 February 2011 - 06:49 AM

Hi try this:
AutoIt         
#include<array.au3> Global $StartPfad = @ScriptDir Global $FileTyp = 'pst' $aFiles = _GetFilesFolder_Rekursiv($StartPfad, $FileTyp, 0, 0, 1) ;~ $aFiles[$aFiles[0]] = StringTrimRight($aFiles[$aFiles[0]], 1) _ArrayDisplay($aFiles) ;================================================================================================== ; Function Name:   _GetFilesFolder_Rekursiv($sPath [, $sExt='*' [, $iDir=-1 [, $iRetType=0 ,[$sDelim='0']]]]) ; Description:  Rekursive Auflistung von Dateien und/oder Ordnern ; Parameter(s): $sPath  der Basispfad für die Auflistung ('.' -aktueller Pfad, '..' -Parentpfad) ;               $sExt   Erweiterung für Dateiauswahl '*' oder -1 für alle (Standard) ;               $iDir   -1 Dateien+Ordner(Standard), 0 nur Dateien, 1 nur Ordner ;   optional:   $iRetType  0 gibt Array, 1 gibt String zurück ;   optional:   $sDelim legt Trennzeichen für Stringrückgabe fest ;                           0 -@CRLF (Standard); 1 -@CR; 2 -@LF; oder beliebiges Zeichen ; Return Value(s): Array (Standard) od. String mit den gefundenen Pfaden der Dateien und/oder Ordner ;               Array[0] enthält die Anzahl der gefundenen Dateien/Ordner ; Author(s):    BugFix (bugfix@autoit.de) ;================================================================================================== Func _GetFilesFolder_Rekursiv($sPath, $sExt = '*', $iDir = -1, $iRetType = 0, $sDelim = '0')     Global $oFSO = ObjCreate('Scripting.FileSystemObject')     Global $strFiles = ''     Switch $sDelim         Case '1'             $sDelim = @CR         Case '2'             $sDelim = @LF         Case Else             $sDelim = @CRLF     EndSwitch     If ($iRetType < 0) Or ($iRetType > 1) Then $iRetType = 0     If $sExt = -1 Then $sExt = '*'     If ($iDir < -1) Or ($iDir > 1) Then $iDir = -1     _ShowSubFolders($oFSO.GetFolder($sPath), $sExt, $iDir, $sDelim)     If $iRetType = 0 Then         Local $aOut         $aOut = StringSplit(StringTrimRight($strFiles, 1), $sDelim, 1)         If $aOut[1] = '' Then             ReDim $aOut[1]             $aOut[0] = 0         EndIf         Return $aOut     Else         Return StringTrimRight($strFiles, 1)     EndIf EndFunc   ;==>_GetFilesFolder_Rekursiv Func _ShowSubFolders($Folder, $Ext = '*', $Dir = -1, $Delim = @CRLF)     If Not IsDeclared("strFiles") Then Global $strFiles = ''     If ($Dir = -1) Or ($Dir = 0) Then         For $file In $Folder.Files             If $Ext <> '*' Then                 If StringRight($file.Name, StringLen($Ext)) = $Ext Then _                         $strFiles &= $file.Path & $Delim             Else                 $strFiles &= $file.Path & $Delim             EndIf         Next     EndIf     For $Subfolder In $Folder.SubFolders         If ($Dir = -1) Or ($Dir = 1) Then $strFiles &= $Subfolder.Path & '\' & $Delim         _ShowSubFolders($Subfolder, $Ext, $Dir, $Delim)     Next EndFunc   ;==>_ShowSubFolders


Mega

Scripts & functions Organize Includes Let Scite organize the include files *new

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users