Что нового

Создать список файлов - PureBasic

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
нашел в инете функцию поиска файлов. накидал примерную dll
не могу понять как сделать на выходе список файлов. справку читал. но пока увы.
вот функция в "моей редакции".
Код:
Procedure Direct(Directory.s) 
  If Right(Directory.s,1)<>"\":Directory.s + "\":EndIf ; Если в конце пути (в конце строки) нет символа '\', то добавлям его.
  z=ExamineDirectory(#PB_Any, Directory.s, "*.*")  ; Начало сканирования папки, путь к которой указан в строковой переменной Directory.
  If z                                             ; Идентификатор (число) сканируемой папки. Он нужен для других функций, например NextDirectoryEntry().
    While NextDirectoryEntry(z)                    ; Переходим к следующему объекту (файлу или папке). Если больше объектов нет - цикл прервется.
      EntryName.s=DirectoryEntryName(z)            ; Имя файла или папки.
      ;------------------------------------------ 
      If EntryName = "." Or EntryName = ".."       ; Если это текущая (".") или родительская ("..") папка,
        Continue                                   ; то досрочно переходим в начало цикла While-Wend.
     EndIf 
     ;------------------------------------------ 
      Type=DirectoryEntryType(z)                   ; Узнаем тип объекта (файл или папка).
      If Type = #PB_DirectoryEntry_Directory   ; Если это папка,
        Direct(Directory.s+EntryName)   ; то процедура вызывает саму себя (рекурсия) для сканирования этой папки.
      ElseIf Type = #PB_DirectoryEntry_File        ; Если это файл,
        ;-------------------------------------------      
      FileName.s = Directory.s+EntryName ; то получаем полный путь к файлу.
      WriteStringN(0,FileName)
      EndIf 
    Wend     
    FinishDirectory(z)                             ; Освобождение ресурсов, используемых при сканировании папки. 
  EndIf 
EndProcedure

ProcedureDLL.s Search (PathF.s,FileW.s)
  CreateFile(0,FileW)
  OpenFile(0,FileW)
  Direct(PathF) 
  CloseFile(0)
EndProcedure
 

sims

Осваивающий
Сообщения
184
Репутация
24
Через файл получится медленно. Лучше передавать список через память.
Код:
Procedure Direct(Directory.s, List Files.s()) 
  If Right(Directory.s,1)<>"\":Directory.s + "\":EndIf ; Если в конце пути (в конце строки) нет символа '\', то добавлям его.
  z=ExamineDirectory(#PB_Any, Directory.s, "*.*")  ; Начало сканирования папки, путь к которой указан в строковой переменной Directory.
  If z                                             ; Идентификатор (число) сканируемой папки. Он нужен для других функций, например NextDirectoryEntry().
    While NextDirectoryEntry(z)                    ; Переходим к следующему объекту (файлу или папке). Если больше объектов нет - цикл прервется.
      EntryName.s=DirectoryEntryName(z)            ; Имя файла или папки.
      ;------------------------------------------ 
      If EntryName = "." Or EntryName = ".."       ; Если это текущая (".") или родительская ("..") папка,
        Continue                                   ; то досрочно переходим в начало цикла While-Wend.
     EndIf 
     ;------------------------------------------ 
      Type=DirectoryEntryType(z)                   ; Узнаем тип объекта (файл или папка).
      If Type = #PB_DirectoryEntry_Directory   ; Если это папка,
        Direct(Directory.s+EntryName, Files())   ; то процедура вызывает саму себя (рекурсия) для сканирования этой папки.
      ElseIf Type = #PB_DirectoryEntry_File        ; Если это файл,
        ;-------------------------------------------      
        FileName.s = Directory.s+EntryName ; то получаем полный путь к файлу.
        If AddElement(Files())
          Files()=FileName
        EndIf
      EndIf 
    Wend     
    FinishDirectory(z)                             ; Освобождение ресурсов, используемых при сканировании папки. 
  EndIf 
EndProcedure

ProcedureDLL Search(PathF.s, *Size.Long)
  Static Dim Result.s(0)
  Protected NewList Files.s()
  
  Direct(PathF, Files())
  *Size\l=ListSize(Files())
  ReDim Result(*Size\l)
  
  i=0
  ForEach Files()
    Result(i)=Files()
    i+1
  Next
  
  ProcedureReturn @Result()
EndProcedure
Код:
$hDLL = DllOpen("ScanFiles.dll")
$Count=0
$Result = DllCall($hDLL, "UINT_PTR", "Search", "STR", "C:\Program Files", "LONG*", $Count)
$Count=$Result[2]
ConsoleWrite($Count & " Файлов найдено" & @CRLF & @CRLF)

$Struct = DllStructCreate("LRESULT var["&$Count&"];",$Result[0])
for $i=0 To $Count
   ConsoleWrite(DllStructGetData($Struct, "var" ,$i) & @CRLF)
next

DllClose($hDLL)
Получаем массив указателей на строки. Как в автоит прочитать строку по указателю, так и не понял.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Через _WinAPI_GetString
А по теме, список файлов вернуть разделенный | на порядок проще.
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
inververs [?]
А по теме, список файлов вернуть разделенный | на порядок проще.
да, проще. но очень долго. две секунды поиск и двадцать формирование строки..это уже ни в какие ворота.
попробуй сам
Код:
ProcedureDLL.s Search(PathF.s)
 Protected NewList Files.s() 
  Direct(PathF, Files())
  ForEach Files()
    String$=String$ + Files() + "|"
  Next
  ProcedureReturn String$
EndProcedure


код вызова функции
Код:
#include <array.au3>
$hDLL = DllOpen("list.dll")
$tr = TimerInit()
$Result = DllCall($hDLL, "str", "Search", "str", "C:\Program Files")
ConsoleWrite(TimerDiff($tr)&@CRLF)
DllClose($hDLL)
$array = StringSplit($Result[0],'|',1)
_ArrayDisplay($array)

в итоге я получаю массив..но потратить минуту...это уж слишком
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Код:
ProcedureDLL.s Search(*proc, PathF.s)
  Protected NewList Files.s() 
  If *proc
    Direct(PathF, Files())
    ForEach Files()
      Define path.s = Files()
      CallFunctionFast(*proc, @path)
    Next
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

Код:
Func Result($sPath)
    ConsoleWrite($sPath & @CRLF)
EndFunc

$hDLL = DllOpen("list.dll")
$tProc = DllCallBackRegister('Result', 'none', 'wstr')
DllCall($hDLL, "none", "Search", "ptr", DllCallbackGetPtr($tProc), "str", @ScriptDir)
DllCallbackFree($tProc)
DllClose($hDLL)
 
Автор
joiner

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
единственное, что использовать 'str' вместо 'wstr'. а то одни вопросики возвращает :smile:
ну и функция тогда должна вызваться не ProcedureDLL.s а ProcedureDLL. иначе дебагер сразу ошибку выдает. что мол ожидается строка , а функция возвращает число
ну а так, виват и ура .
 
Верх