Sign in to follow this  
Followers 0
nivtop

Filename exists auto rename making too many duplicates

10 posts in this topic

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

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

Share this post


Link to post
Share on other sites



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.

Share this post


Link to post
Share on other sites

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.

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

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Another way without using File Handles and FileClose ...

Function:

; #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:

#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 as well.

Edited by guinness

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_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()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_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()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

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

Function:

#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

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_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()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_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()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

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)

Share this post


Link to post
Share on other sites

Thx everyone for the input

helped me out

Share this post


Link to post
Share on other sites

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

Thx

Share this post


Link to post
Share on other sites

Hi try this:

#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

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

Share this post


Link to post
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
Sign in to follow this  
Followers 0