Announcement

Collapse
No announcement yet.

Finding all the files in a user selected folder

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Finding all the files in a user selected folder

    I found some nice code in the ever usefull Poffs forum for asking the user
    to point to a folder. Now I want to process all the files in that folder.

    While LastFile = 0
    LastFile = GetNextFile ' function
    If LastFile = 0 then Result = ProcessFile 'function
    Wend

    How do you experts do this?

    Regards
    Mike

    ------------------
    Kind Regards
    Mike

  • #2
    Nor sure this what you want, but following populates a listbox with all files
    in defined folder. Remove the LB_ messages if you don't need them and, voilá.
    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Populate Listbox with all files in a folder
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    SUB FilesToList(BYVAL hWnd AS LONG, BYVAL AbsPath AS STRING)
      LOCAL hSearch AS LONG, WFD AS WIN32_FIND_DATA
     
      IF RIGHT$(AbsPath, 1) <> "\" THEN AbsPath = AbsPath & "\*"
     
      hSearch = FindFirstFile(BYVAL STRPTR(AbsPath), WFD) 'Get search handle
      IF hSearch <> %INVALID_HANDLE_VALUE THEN
         CALL SendMessage(hWnd, %LB_RESETCONTENT, 0, 0)   'clear listbox
         DO
            IF (WFD.dwFileAttributes AND 16) = 0 THEN     'No dirs, please..
               CALL SendMessage(hWnd, %LB_ADDSTRING, 0, BYVAL VARPTR(WFD.cFileName))
            END IF
         LOOP WHILE FindNextFile(hSearch, WFD) ' Get next file
         CALL FindClose(hSearch)
      END IF
    END SUB

    ------------------


    [This message has been edited by Borje Hagsten (edited July 05, 2001).]

    Comment


    • #3
      Easiest solution without API:

      Code:
      CHDIR targetdirectory$
      
      mask$ = "*.*"
      
      file$ = Dir$(mask$)
      
      DO WHILE LEN(file$)
      
      'file$ contains now the filename. do what you want with it.
      
      file$ = DIR$
      LOOP

      ------------------
      E-Mail (home): mailto:[email protected][email protected]</A>
      E-Mail (work): mailto:[email protected][email protected]</A>

      [This message has been edited by Sven Blumenstein (edited July 05, 2001).]

      Comment


      • #4
        I was thinking (trying, anyway). If to look for *.*, folders with a
        dot in the name will be included? Same when looking for files with *.*,
        then files without a prefix won't be found? Think one better check the
        attributes and use single *, otherwise strange things may happen.

        MS's crappy and sometimes dangerous LFN support sure can mess up things.
        I have a file search utility here that always missed one file. After hard
        detective work, I found that I excluded files that started with a dot,
        and found a file that did just this. Some weird CGI-file, called .redirect


        ------------------

        Comment


        • #5
          This little function gives you all files in a string-array.
          It will return number of files found.
          Code:
          Function FSO_GetFiles(ByVal PathSpec$,ByVal FileMask$,Filer()As String)As Long
          Local fd As WIN32_FIND_DATA
          Local fAttr As Dword
          Local cnt&,hFind&
          
            If Len(PathSpec$) = 0 Then Function = 0:Exit Function
            If FSO_FolderExists(PathSpec$) = %false Then Function = 0:Exit Function
          '..samla ihop filerna..........
            On Error Resume Next
            If Right$(PathSpec$,1)<>"\" Then PathSpec$=PathSpec$ & "\"
            PathSpec$ = PathSpec$ & Mask$
            ReDim Filer(1 To 1)As String
            cnt& = 0
            hFind&    = FindFirstFile(ByVal StrPtr(PathSpec$), fd)
            If hFind& = %INVALID_HANDLE_VALUE Then Function = %false :Exit Function
            Do
              If (Bit(fd.dwFileAttributes,4)= 0) And (Bit(fd.dwFileAttributes,8)=0) Then
               Incr cnt&
               ReDim Preserve Filer(1 To cnt&)
               Filer(cnt&) = Rtrim$(fd.cFileName,Any Chr$(0,32))
              End If
              If IsFalse FindNextFile(hFind&,fd) Then Call FindClose(hFind&):Exit Do
            Loop
            Array Sort Filer(),Collate Ucase
            Function = cnt&
          End Function
            
          Usage:
          Local wFile() as string
            Redim wFile(1 to 1)
            cnt& = FSO_GetFiles("C:\WINDOWS\","*.DLL",wFile()
            For i& = 1 to cnt%
             Do your processing of wFile(i&)
            Next
          ------------------
          Fred
          mailto:[email protected][email protected]</A>
          http://www.oxenby.se

          Fred
          mailto:[email protected][email protected]</A>
          http://www.oxenby.se

          Comment


          • #6
            Just one un-important tip, Fred. Tried the (Bit(fd.dwFileAttributes,4) = 0
            -way in my file search and found that using (WFD.dwFileAttributes AND 16) = 0
            is faster. Natural cause, BIT() is a function call, AND makes bitwise compare
            directly..


            ------------------

            Comment


            • #7
              Fred,

              thx this looks like what I want.
              Im a little stuck in the passing array stuff tho ...

              If you REDIM an array in a function How does the calling function know
              that it needs to REDIM itself. For example

              Code:
              FUNCTION test( a() AS STRING ) AS LONG
              REDIM a(9)
                  FOR i& = 1 TO 9
                      a(i&) = STR$(i&)
                  NEXT
              END FUNCTION
              '-----------------------------
              PBMAIN
              LOCAL b() AS STRING
              DIM b(1)
              
                  CALL test( b() )    
                  ' b() is still 1 element ??
              
              END FUNCTION
              ------------------
              Kind Regards
              Mike



              [This message has been edited by Mike Trader (edited July 06, 2001).]

              Comment


              • #8
                The array is passed by reference, so any changes to it are passed back
                to the caller. Check out the LBOUND and UBOUND functions for dealing
                with this sort of thing.

                ------------------
                Tom Hanlin
                PowerBASIC Staff

                Comment


                • #9
                  Wow! thats so cool!
                  This is a powerfull language.

                  So here is what i ended up with for those who read this thread later.

                  Code:
                  #COMPILE EXE "FldrCts.exe"
                  #INCLUDE     "WIN32API.INC" ' Win API definitions
                  '#INCLUDE     "DlgFns32.bas" ' for selecting a folder
                  
                  '-----------------------------------------------------------------------------------
                  FUNCTION FolderFiles(BYVAL Path AS STRING, BYVAL FileMask AS STRING, Files()AS STRING) AS LONG
                  LOCAL wfd AS WIN32_FIND_DATA
                  LOCAL fAttr AS DWORD, PathAndMask AS STRING
                  LOCAL Count AS LONG, hFind AS LONG
                      IF LEN(Path) = 0 THEN EXIT FUNCTION ' bad call
                      ON ERROR RESUME NEXT
                      IF RIGHT$(Path, 1) <> "\" THEN Path = Path + "\" ' Fix up Path
                      PathAndMask = Path + "*.*"
                      hFind       = FINDFIRSTFILE(BYVAL STRPTR(PathAndMask), wfd)
                      IF hFind    = %INVALID_HANDLE_VALUE THEN MSGBOX "Folder Does Not Exist!",,"Error" : EXIT FUNCTION ' Test for valid dir
                      PathAndMask = Path + FileMask
                      REDIM Files(1) ' erase the array
                      hFind       = FINDFIRSTFILE(BYVAL STRPTR(PathAndMask), wfd)
                      IF hFind    = %INVALID_HANDLE_VALUE THEN EXIT FUNCTION ' Exit if no matching files
                      Count = 0 ' starting value
                      DO
                          IF (WFD.dwFileAttributes AND 16) = 0 THEN  ' No dirs please..
                              INCR Count
                              REDIM PRESERVE Files(Count)
                              Files(Count) = RTRIM$(wfd.cFileName, ANY CHR$(0,32))
                          END IF
                          IF ISFALSE FINDNEXTFILE(hFind, wfd) THEN CALL FINDCLOSE(hFind) : EXIT DO
                          IF Count > 9999 THEN EXIT DO ' Protection
                      LOOP
                      ARRAY SORT Files(), COLLATE UCASE
                      FUNCTION    = Count
                  END FUNCTION
                  '-----------------------------------------------------------------------------------
                  FUNCTION PBMAIN()AS LONG
                  LOCAL i AS LONG, NumFiles AS LONG
                  LOCAL Fi() AS STRING, TempStr AS ASCIIZ*%max_Path
                  DIM Fi(1)
                      TempStr  = "C:\PBDLL60\BIN" ' Starting Directory
                     'IF FolderDialog( 0, "Select a folder", TempStr ) = 0 THEN EXIT FUNCTION  ' see the thread on selecting a folder
                      NumFiles = FolderFiles( TempStr, "*.txt", Fi() )
                      IF NumFiles = 0 THEN MSGBOX "No matching files found"
                      FOR i = 1 TO NumFiles
                          MSGBOX Fi(i),," File "+STR$(i)+" of "+STR$(NumFiles)
                      NEXT
                  END FUNCTION
                  Thx for all your help esp Fred

                  ------------------
                  Kind Regards
                  Mike



                  [This message has been edited by Mike Trader (edited July 06, 2001).]

                  Comment


                  • #10
                    Mike, Do you have some reason to maximize number of files found?
                    I use this function in folders with 100,000 files.....


                    ------------------
                    Fred
                    mailto:[email protected][email protected]</A>
                    http://www.oxenby.se

                    Fred
                    mailto:[email protected][email protected]</A>
                    http://www.oxenby.se

                    Comment


                    • #11
                      100,000 files!!

                      yikes fred. If any of my users get anywhere near 1000
                      then they have accidentally screwed up an will have to
                      sit for a long time while the rest of the code ploughs through the tests.

                      but you are right that test belongs outside the function.
                      I just get nervous about open ended Do loops when I dont fully
                      understand exactly whats going on. Alot of my programming is
                      "monkey see monkey do" Im the monkey that left alone at a keyboard
                      long enough will come up with something that passes the sniff test
                      any closer examination and, er well ....

                      I just decided that I will never have the time to really study
                      programming like I wanted to in college when none of these tools
                      were available, So im just gonna be in kindergarten, have fun
                      and fake it


                      ------------------
                      Kind Regards
                      Mike

                      Comment

                      Working...
                      X