Jump to content
Sign in to follow this  
AZJIO

_FileSearch + _FolderSearch

Recommended Posts

Trying to make a function to filter by attributes

#include <Array.au3> ; для _ArrayDisplay
#include <FileOperations.au3>

$FileList = _FO_FileSearch(@SystemDir & 'drivers', '*.sys')
$cn = $FileList[0]

$Filters = 'RHS'

$timer = TimerInit()
; _AttribFilters($FileList, $Filters, 0, 1)
_AttribFilters($FileList, $Filters, 0, 0)
$timer = Round(TimerDiff($timer) / 1000, 2) & ' sec'
; _ArrayDisplay($FileList, $timer & ', ' & $cn)
MsgBox(0, 'FileList, ' & $cn & ', ' & $Filters & ', ' & $timer, $FileList)

Func _AttribFilters(ByRef $aFileList, $sAttrib, $iExclude = 1, $iArray = 1)
    $sAttrib = StringRegExpReplace(StringUpper($sAttrib), '[^RASHNOT]', '')
    If Not $sAttrib Then Return SetError(2, 0, '')
    If $iExclude Then $sAttrib = '^' & $sAttrib

    If $iArray Then
        $c = 0
        For $i = 1 To $aFileList[0]
            $sFileAttrib = FileGetAttrib($aFileList[$i])
            If StringRegExp($sFileAttrib, '[' & $sAttrib & ']') Then
                $c += 1
                $aFileList[$c] = $aFileList[$i]
            EndIf
        Next
        If $c Then
            $aFileList[0] = $c
            ReDim $aFileList[$c + 1]
        Else
            Dim $aFileList[1] = [0]
            Return SetError(3, 0, '')
        EndIf
    Else
        $c = ''
        For $i = 1 To $aFileList[0]
            $sFileAttrib = FileGetAttrib($aFileList[$i])
            If StringRegExp($sFileAttrib, '[' & $sAttrib & ']') Then
                $c &= $aFileList[$i] & @CRLF
            EndIf
        Next
        $c = StringTrimRight($c, 2)
        If $c Then
            $aFileList = $c
        Else
            Return SetError(3, 0, '')
        EndIf
    EndIf
EndFunc

Speed test

if Len($sAttrib)>4 Then Time(SPE) < Time(StringInStr)

Global $aFileAttrib[8] = [7, _
        'RASH', _
        'R', _
        'A', _
        'SH', _
        'RSH', _
        'ASH', _
        'RASHNOT']
$sAttrib = 'RSHT'

$timer = TimerInit()
$c1 = _AttribFilters($aFileAttrib, $sAttrib)
$d1 = @extended
$t1 = Round(TimerDiff($timer), 2) & ' msec'

$timer = TimerInit()
$c2 = _AttribFilters1($aFileAttrib, $sAttrib)
$d2 = @extended
$t2 = Round(TimerDiff($timer), 2) & ' msec'
MsgBox(0, '', _
'StrStr:' & @Tab & $c1 & @Tab & $d1 & @Tab & $t1 & @CRLF & _
'SPE..:' & @Tab & $c2 & @Tab & $d2 & @Tab & $t2)

Func _AttribFilters($aFileAttrib, $sAttrib)
    Local $c = 0, $d = 0
    $asAttrib = StringSplit($sAttrib, '')
    If @error Then Return

    For $s = 1 To 1000
        For $i = 1 To $aFileAttrib[0]
            For $j = 1 To $asAttrib[0]
                If StringInStr($aFileAttrib[$i], $asAttrib[$j]) Then
                    $d += 1
                    ContinueLoop 2
                EndIf
            Next
            $c += 1
        Next
    Next
    Return SetError(0, $d, $c)
EndFunc

Func _AttribFilters1($aFileAttrib, $sAttrib)
    Local $c = 0, $d = 0
    For $s = 1 To 1000
        For $i = 1 To $aFileAttrib[0]
            If StringRegExp($aFileAttrib[$i], '[' & $sAttrib & ']') Then
                $d += 1
            Else
                $c += 1
            EndIf
        Next
    Next
    Return SetError(0, $d, $c)
EndFunc
Edited by AZJIO

Share this post


Link to post
Share on other sites

how do a search for a specefic file, and return the result, if it is found

#include <Array.au3> ; _ArrayDisplay
#include <FileOperations.au3>

; Example 1
$aFileList = _FO_FileSearch('C:WINDOWSsystem', 'specific_file.tmp')
If Not @error Then _ArrayDisplay($aFileList)

; Example 2
$aFileList = _FO_FileSearch(@WindowsDir, 'shell32.dll')
If Not @error Then _ArrayDisplay($aFileList)

; Example 3
$sFileList = _FO_FileSearch(@WindowsDir, 'shell32.dll', True, 125, 1, 0)
If Not @error Then MsgBox(0, 'Yes?', $sFileList)
Edited by AZJIO

Share this post


Link to post
Share on other sites

the code you wrote in #21

Is there a way to exclude a folder, so it doesn't search in a specified folder?

I want to search the content for diffrent drives for .txt files, ex d: but exclude a folder on d:\

Edited by legend

Share this post


Link to post
Share on other sites

Need to get a list of folders, and then do a search for each folder, except the specified. The folder you exclude can be in other directories. This will give the wrong result. So I did not add in the option to exclude folders.

A little later I'll do an example, but not for the UDF.

Share this post


Link to post
Share on other sites

#include <Array.au3> ; _ArrayDisplay
#include <FileOperations.au3>

$FileList = _FO_FileSearchExceptions(@HomeDrive, '*exe', True, '*Settings|MSOCache|Program Files|RECYCLER|System Volume Information|WINDOWS', 125, 1, 0)
MsgBox(0, @error, $FileList)

; $FileList = _FO_FileSearchExceptions(@HomeDrive, '*exe', True, '*Settings|MSOCache|Program Files|RECYCLER|System Volume Information|WINDOWS')
; _ArrayDisplay($FileList)

Func _FO_FileSearchExceptions($sPath, $sMask = '*', $fInclude = True, $sExceptions = '', $iDepth = 125, $iFull = 1, $iArray = 1, $iTypeMask = 1, $sLocale = 0)
    Local $vFolderList
    If Not $sExceptions Then
        $vFolderList = _FO_FileSearch($sPath, $sMask, $fInclude, $iDepth, $iFull, $iArray, $iTypeMask, $sLocale)
        Return SetError(@error, 0, $vFolderList)
    EndIf

    Local $i, $rgex, $vFileList = ''
    $vFolderList = _FO_FolderSearch($sPath, '*', True, 0, 0, 0)
    If @error Then
        $vFolderList = _FO_FileSearch($sPath, $sMask, $fInclude, $iDepth, $iFull, $iArray, $iTypeMask, $sLocale)
        Return SetError(@error, 0, $vFolderList)
    EndIf

    $sExceptions = StringReplace(StringReplace(StringRegExpReplace($sExceptions, '[][$^.{}()+]', '$0'), '?', '.'), '*', '.*?')

    If Not $sLocale Then
        $rgex = 'i'
    ElseIf Not ($sLocale == '1') Then
        $rgex = 'i'
        $sExceptions = __FO_UserLocale($sExceptions, $sLocale)
    EndIf

    $vFolderList = StringTrimRight(StringRegExpReplace($vFolderList & @CRLF, '(?m' & $rgex & ')^(' & $sExceptions & ')rn', ''), 2)
    If Not $vFolderList Then
        $vFolderList = _FO_FileSearch($sPath, $sMask, $fInclude, $iDepth, $iFull, $iArray, $iTypeMask, $sLocale)
        Return SetError(@error, 0, $vFolderList)
    EndIf
    ; MsgBox(0, '???', '|' & $vFolderList & '|')
    $vFolderList = StringSplit($vFolderList, @CRLF, 1)
    ; _ArrayDisplay($vFolderList)
    For $i = 1 To $vFolderList[0]
        $vFileList &= _FO_FileSearch($sPath & '' & $vFolderList[$i], $sMask, $fInclude, $iDepth, 1, 0, $iTypeMask, $sLocale)
        If Not @error Then $vFileList &= @CRLF
    Next
    $vFileList &= _FO_FileSearch($sPath, $sMask, $fInclude, 0, 1, 0, $iTypeMask, $sLocale) ; ???
    If @error Then $vFileList = StringTrimRight($vFileList, 2)
    ; $vFileList = StringTrimRight($vFileList, 2)

    If Not $vFileList Then Return SetError(3, 0, '')
    Switch $iFull
        Case 0
            $vFileList = StringRegExpReplace($vFileList, '(?m)^(?:.{' & StringLen($sPath) & '})(.*)$', '1')
        Case 2
            $vFileList = StringRegExpReplace($vFileList, '(?m)^(?:.*)(.*)$', '1')
        Case 3
            $vFileList = StringRegExpReplace($vFileList, '(?m)^(?:.*)([^]*?)(?:.[^.]+)?$', '1' & @CR)
            $vFileList = StringTrimRight($vFileList, 1)
    EndSwitch
    Switch $iArray
        Case 1
            $vFileList = StringSplit($vFileList, @CRLF, 1)
        Case 2
            $vFileList = StringSplit($vFileList, @CRLF, 3)
    EndSwitch
    Return $vFileList
EndFunc   ;==>_FO_FileSearchExceptions

Edited by AZJIO

Share this post


Link to post
Share on other sites

I added the option $vExcludeFolders

 

$$vExcludeFolders - Excludes folders from search, only the root. List the folder names via the "|", for example, "Name1|Name2|Name3|".

 

FileOperations.7z

The main file is not updated, but I think I will leave this option. The search speed is not reduced and the exclusion of unnecessary search faster.

 

Share this post


Link to post
Share on other sites

How it is more convenient to pass a list of exceptions? As a single parameter or as a component?

$sPath = 'C:\Program Files\<Program Files|WINDOWS>'
_FO_FileSearch_Test($sPath)

Func _FO_FileSearch_Test($sPath)
    If StringRight($sPath, 1) = '>' Then
        $iPos = StringInStr($sPath, '<', 1, -1)
        $vExcludeFolders = StringTrimRight(StringTrimLeft($sPath, $iPos), 1)
        $sPath = StringLeft($sPath, $iPos - 1)
    EndIf
    MsgBox(0, 'Сообщение', $sPath & @LF & $vExcludeFolders)
EndFunc

Share this post


Link to post
Share on other sites

To me reported about a mistake in version 1.7. When testing the 1.6 version works fine.

At version 1.7, an error (Win7 x64)

previously called with Const or expression on ByRef param

 

C:Program Files (x86)AutoIt3IncludeFileOperations.au3(238,155) : ERROR: __FO_FileSearchType() previously called with Const or expression on ByRef param(s).
Func __FO_FileSearchType(ByRef $sFileList, $sPath, ByRef $sMask, ByRef $fInclude, ByRef $iDepth, ByRef $aExcludeFolders, ByRef $iExcludeDepth, $iCurD = 0)

C:\Program Files (x86)\AutoIt3\Include\FileOperations.au3(147,118) : REF: first call to __FO_FileSearchType().
               __FO_FileSearchType($vFileList, $sPath, '|' & $sMask & '|', $fInclude, $iDepth, $vExcludeFolders, $iExcludeDepth) 
#include <Array.au3> ; for _ArrayDisplay
#include <FileOperations.au3>

$timer = TimerInit()
$FileList = _FO_FileSearch(@WindowsDir, 'exe|dll|txt|zip', True, 2, 0, 1, 2, 0, 'system32', 0)
$timer = Round(TimerDiff($timer) / 1000, 2) & ' sec'
_ArrayDisplay($FileList, 'timer ' & $timer)

I checked on Win7 x64, Win8 x64, there were no errors. I used to save memory ByRef. So that when the depth of recursion 20 used one copy.

Has anyone any thoughts on this?

Edited:

Apparently gives Au3Check.exe error when run from Scite.exe

Edited by AZJIO

Share this post


Link to post
Share on other sites

This error should go away in the new betas and stable release. I'm not sure if this is just an Au3Check error, but I don't think so. The issue is you can only use a non Const variable as an argument to a ByRef function parameter. In your example, you're passing a string -  '|' & $sMask & '|' - which is not allowed.

You could work around it by setting the value of $sMask =  '|' & $sMask & '|' before calling the function, and passing just $sMask.

Edited by wraithdu

Share this post


Link to post
Share on other sites

 

string -  '|' & $sMask & '|' - which is not allowed.

Func __FO_FileSearchType(ByRef $sFileList, $sPath, ByRef $sMask, ByRef $fInclude, ByRef $iDepth, ByRef $aExcludeFolders, ByRef $iExcludeDepth, $iCurD = 0)

In the previous message it was not mine

I disabled the enforced validation

AutoIt3Wrapper.ini

[Other]

Run_AU3Check=n

Edited by AZJIO

Share this post


Link to post
Share on other sites

Reported a new problem:

If a symbolic link to a directory is in the same directory, then it leads to an infinite loop.

c:ProgramData -> Application Data -> c:ProgramData ...etc

GetFileAttributes? FILE_ATTRIBUTE_REPARSE_POINT?

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...