Re: Could this be faster?

new topic     » goto parent     » topic index » view thread      » older message » newer message

I though I'd try walk_dir using the windows API.
This appears to be about 3 times faster, YMMV.
It uses arwen, though it should be relatively trivial to change
the constants to conform to win32lib.

include arwen.ew
constant 
    -- Define FINDDATA Structure
    FINDDATA                = new_struct(),
    FINDDATA_dwAttr         = struc(C_LONG),
    FINDDATA_Times3         = struc(anySize(24)),
    FINDDATA_nFileSizeHigh  = struc(C_LONG),
    FINDDATA_nFileSizeLow   = struc(C_LONG),
    FINDDATA_res2           = struc(anySize(8)),
    FINDDATA_cFileName      = struc(anySize(260)),
    FINDDATA_cAltFileName   = struc(anySize(14)),

    fd = allocate(sizeof(FINDDATA)),

    xFindFirstFile  = link_c_func(kernel32, "FindFirstFileA",
        {C_POINTER, --  LPCTSTR  lpFileName,    // address of name of
        file to search for  
         C_POINTER},--  LPWIN32_FIND_DATA  lpFindFileData   // address
         of returned information 
        C_LONG),    -- HANDLE

    xFindNextFile   = link_c_func(kernel32, "FindNextFileA",
        {C_POINTER, --  HANDLE  hFindFile,  // handle of search  
         C_POINTER},--  LPWIN32_FIND_DATA  lpFindFileData   // address
         of structure for data on found file  
        C_INT),     -- BOOL

    xFindClose      = link_c_func(kernel32, "FindClose",
        {C_POINTER},--  HANDLE  hFindFile   // file search handle 
        C_INT),     -- BOOL

    INVALID_HANDLE_VALUE=-1

function get_file_ext(sequence filename)
integer c
    for i=length(filename) to 1 by -1 do
        c = filename[i]
        if c = '.' then
            return filename[i+1..length(filename)]
        elsif c>='A' and c<='Z' then
            filename[i] = c+32
        end if
    end for
    return ""
end function

procedure wd(sequence path)
-- walk_dir coded using winAPI direct.
-- results not in any particular order.
integer d
atom fH, attr
sequence longname
sequence ipath
sequence dirstack

    ipath = path
    dirstack={}

    if platform()!=2 then ?9/0 end if   --Win32 only supported

    while 1 do
        --
        -- Force consistent use of '\\' vs '/'.
        --
        d=find('/',path)
        if d=0 then exit end if
        path[d]='\\'
    end while

    fH=INVALID_HANDLE_VALUE
    if length(path) and path[length(path)]='\\' then
        path&="*.*"
    elsif length(path) and path[length(path)]=':' then
        ipath = path&'\\'
        path&="\\*.*"
    --NB I doubt this will work with wildcards!
    elsif not find('*',path) and not find('?',path) then
        --
        -- Check if the passed path is a directory;
        -- if it is, list it's contents, not just it.
        --
        fH = c_func(xFindFirstFile,{allocate_StringZ(path),fd})
        if fH!=INVALID_HANDLE_VALUE then
            attr = peek4u(fd + FINDDATA_dwAttr)
            if and_bits(attr,#10) then  -- directory bit
                ipath&='\\'
                path&="\\*.*"
                if c_func(xFindClose,{fH}) then end if
                fH=INVALID_HANDLE_VALUE
            end if
        end if
    end if
    if fH=INVALID_HANDLE_VALUE then
        fH = c_func(xFindFirstFile,{allocate_StringZ(path),fd})
    end if
    if fH!=INVALID_HANDLE_VALUE then
        while 1 do
            attr = peek4u(fd + FINDDATA_dwAttr)
            longname = peek_string(fd + FINDDATA_cFileName)
            if and_bits(attr,#10) then
                if not find(longname,{".",".."}) then
                    dirstack = append(dirstack,ipath&longname)
                end if
            else
                if find(get_file_ext(longname),{"aac","mp4", "mp3",
                "mp2", "mp1", "ogg", "wav"}) then
-- DEV: call external routine/append to result stack
                    puts(1,longname&'\n')
                end if
            end if
            if not c_func(xFindNextFile,{fH,fd}) then exit end if
        end while
        if c_func(xFindClose,{fH}) then end if
        for i=1 to length(dirstack) do
            wd(dirstack[i])
        end for
    end if
end procedure
wd("C:\\")


Regards,
Pete

-- 
  
  petelomax at fastmail.fm

-- 
http://www.fastmail.fm - Access your email from home and the web

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu