OVH Cloud OVH Cloud

recherche plein texte d'explorer

16 réponses
Avatar
Francois
Bonjour,

Je souhaiterais utiliser dans un programme la recherche plein texte de MS
Explorer afin de trouver dans une série de fichiers certains mots clé. J'ai
pu arriver à ce résultat par programmation, mais ça prends 10 fois plus de
temps que celle d'Explorer (30s contre 3s...)...
Y a t'il une API à utiliser ou un paramètre à envoyer à Explorer via une
commande Shell de manière à ce que ce soit ce moteur de recherche de Windows
qui soit exécuté ?

Merci.

François

10 réponses

1 2
Avatar
ng
Salut,

Ta recherche porte sur le nom du fichier ou sur son contenu ?

Sinon il y a les APIs FindFirstfile/NextFile/Close() :

'Create a form with a command button (command1), a list box (list1)
'and four text boxes (text1, text2, text3 and text4).
'Type in the first textbox a startingpath like c:
'and in the second textbox you put a pattern like *.* or *.txt

Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA"
(ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA"
(ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function GetFileAttributes Lib "kernel32" Alias
"GetFileAttributesA" (ByVal lpFileName As String) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long)
As Long

Const MAX_PATH = 260
Const MAXDWORD = &HFFFF
Const INVALID_HANDLE_VALUE = -1
Const FILE_ATTRIBUTE_ARCHIVE = &H20
Const FILE_ATTRIBUTE_DIRECTORY = &H10
Const FILE_ATTRIBUTE_HIDDEN = &H2
Const FILE_ATTRIBUTE_NORMAL = &H80
Const FILE_ATTRIBUTE_READONLY = &H1
Const FILE_ATTRIBUTE_SYSTEM = &H4
Const FILE_ATTRIBUTE_TEMPORARY = &H100

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type
Function StripNulls(OriginalStr As String) As String
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function

Function FindFilesAPI(path As String, SearchStr As String, FileCount As
Integer, DirCount As Integer)
'KPD-Team 1999
'E-Mail:
'URL: http://www.allapi.net/

Dim FileName As String ' Walking filename variable...
Dim DirName As String ' SubDirectory Name
Dim dirNames() As String ' Buffer for directory name entries
Dim nDir As Integer ' Number of directories in this path
Dim i As Integer ' For-loop counter...
Dim hSearch As Long ' Search Handle
Dim WFD As WIN32_FIND_DATA
Dim Cont As Integer
If Right(path, 1) <> "" Then path = path & ""
' Search for subdirectories.
nDir = 0
ReDim dirNames(nDir)
Cont = True
hSearch = FindFirstFile(path & "*", WFD)
If hSearch <> INVALID_HANDLE_VALUE Then
Do While Cont
DirName = StripNulls(WFD.cFileName)
' Ignore the current and encompassing directories.
If (DirName <> ".") And (DirName <> "..") Then
' Check for directory with bitwise comparison.
If GetFileAttributes(path & DirName) And
FILE_ATTRIBUTE_DIRECTORY Then
dirNames(nDir) = DirName
DirCount = DirCount + 1
nDir = nDir + 1
ReDim Preserve dirNames(nDir)
End If
End If
Cont = FindNextFile(hSearch, WFD) 'Get next subdirectory.
Loop
Cont = FindClose(hSearch)
End If
' Walk through this directory and sum file sizes.
hSearch = FindFirstFile(path & SearchStr, WFD)
Cont = True
If hSearch <> INVALID_HANDLE_VALUE Then
While Cont
FileName = StripNulls(WFD.cFileName)
If (FileName <> ".") And (FileName <> "..") Then
FindFilesAPI = FindFilesAPI + (WFD.nFileSizeHigh * MAXDWORD)
+ WFD.nFileSizeLow
FileCount = FileCount + 1
List1.AddItem path & FileName
End If
Cont = FindNextFile(hSearch, WFD) ' Get next file
Wend
Cont = FindClose(hSearch)
End If
' If there are sub-directories...
If nDir > 0 Then
' Recursively walk into them...
For i = 0 To nDir - 1
FindFilesAPI = FindFilesAPI + FindFilesAPI(path & dirNames(i) &
"", SearchStr, FileCount, DirCount)
Next i
End If
End Function
Sub Command1_Click()
Dim SearchPath As String, FindStr As String
Dim FileSize As Long
Dim NumFiles As Integer, NumDirs As Integer
Screen.MousePointer = vbHourglass
List1.Clear
SearchPath = Text1.Text
FindStr = Text2.Text
FileSize = FindFilesAPI(SearchPath, FindStr, NumFiles, NumDirs)
Text3.Text = NumFiles & " Files found in " & NumDirs + 1 & "
Directories"
Text4.Text = "Size of files found under " & SearchPath & " = " &
Format(FileSize, "#,###,###,##0") & " Bytes"
Screen.MousePointer = vbDefault
End Sub


--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/

Francois wrote:
Bonjour,

Je souhaiterais utiliser dans un programme la recherche plein texte
de MS Explorer afin de trouver dans une série de fichiers certains
mots clé. J'ai pu arriver à ce résultat par programmation, mais ça
prends 10 fois plus de temps que celle d'Explorer (30s contre
3s...)...
Y a t'il une API à utiliser ou un paramètre à envoyer à Explorer via
une commande Shell de manière à ce que ce soit ce moteur de recherche
de Windows qui soit exécuté ?

Merci.

François


Avatar
Francois
Bonjour ng,

La recherche porte sur le contenu... La solution que j'utilise est celle
d'ouvrir le fichier en mode binaire et de le stocker dans une variable et de
faire une recherche de caractère dans cette variable, mais cette solution
peut prendre 3 à 4 s pour les gros fichiers => 300 docs = beaucoup de
temps... Explorer va + vite que ça.

Merci

"ng" a écrit dans le message news:
OlepG$
Salut,

Ta recherche porte sur le nom du fichier ou sur son contenu ?

Sinon il y a les APIs FindFirstfile/NextFile/Close() :


Avatar
Jean-Marc
Hello,

pour le parcours, faire comme indiqué par ng.
Pour le contenu, pas beaucoup de choix si tu veux
vraiment des performances:
- Implémenter en C une fonction de recherche utilisant
l'algorithme de BOYER MOORE. Rien de plus rapide, en
tout cas pour ce que tu veux faire.

- Implémenter en VB, mais en jouant avec les API de
manipulation mémoire, l'algorithme de BOYER MOORE.
Mais dans ce cas, pour quoi le faire en VB? Ca prend
2 heures de le faire en C proprement.

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."
"Francois" a écrit dans le message de
news:
Bonjour ng,

La recherche porte sur le contenu... La solution que j'utilise est celle
d'ouvrir le fichier en mode binaire et de le stocker dans une variable et


de
faire une recherche de caractère dans cette variable, mais cette solution
peut prendre 3 à 4 s pour les gros fichiers => 300 docs = beaucoup de
temps... Explorer va + vite que ça.

Merci

"ng" a écrit dans le message news:
OlepG$
> Salut,
>
> Ta recherche porte sur le nom du fichier ou sur son contenu ?
>
> Sinon il y a les APIs FindFirstfile/NextFile/Close() :





Avatar
Francois
Bonjour

Merci à vous 2, Jean Marc et ng pour les pistes que vous m'avez donné, je
vais voir ce que je peux faire avec ça.

A+

François


"Jean-Marc" a écrit dans le message news:
41769a8e$0$22750$
Hello,

pour le parcours, faire comme indiqué par ng.
Pour le contenu, pas beaucoup de choix si tu veux
vraiment des performances:
- Implémenter en C une fonction de recherche utilisant
l'algorithme de BOYER MOORE. Rien de plus rapide, en
tout cas pour ce que tu veux faire.

- Implémenter en VB, mais en jouant avec les API de
manipulation mémoire, l'algorithme de BOYER MOORE.
Mais dans ce cas, pour quoi le faire en VB? Ca prend
2 heures de le faire en C proprement.

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."


Avatar
ng
Salut,

Peut-on voir ta procédure d'ouvertur de fichier ?

--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/

Francois wrote:
Bonjour,

Je souhaiterais utiliser dans un programme la recherche plein texte
de MS Explorer afin de trouver dans une série de fichiers certains
mots clé. J'ai pu arriver à ce résultat par programmation, mais ça
prends 10 fois plus de temps que celle d'Explorer (30s contre
3s...)...
Y a t'il une API à utiliser ou un paramètre à envoyer à Explorer via
une commande Shell de manière à ce que ce soit ce moteur de recherche
de Windows qui soit exécuté ?

Merci.

François


Avatar
Gloops
Salut,

Je me demande si il n'y aurait pas une troisième voie : faire un appel à
l'explorateur Windows, à l'aide d'un Shell par exemple. ça doit être
plus gourmand en mémoire, mais en temps de développement en revanche ...
________________________________________
Jean-Marc a écrit, le 20/10/2004 19:04 :

Hello,

pour le parcours, faire comme indiqué par ng.
Pour le contenu, pas beaucoup de choix si tu veux
vraiment des performances:
- Implémenter en C une fonction de recherche utilisant
l'algorithme de BOYER MOORE. Rien de plus rapide, en
tout cas pour ce que tu veux faire.

- Implémenter en VB, mais en jouant avec les API de
manipulation mémoire, l'algorithme de BOYER MOORE.
Mais dans ce cas, pour quoi le faire en VB? Ca prend
2 heures de le faire en C proprement.



Avatar
Francois
Bonjour,

En fait, je suis sur Access et les docs dont les chemins sont connus de la
base peuvent être sur le réseau et sur des postes distant => Le langage VB
m'irait très bien car si je passais en C, je sens qu'il faudrait que je gère
les chemins réseaux... ce qui n'est pas de la tarte...
Les documents sont de différents type (Word, XL, PDF, HTML).

Voici des extraits de la fonction d'ouverture :

Fnum = FreeFile

On Error Resume Next
Open Fic For Binary As #Fnum
If Err.Number = 0 Then
On Error GoTo Err_adRecherchePleinTxt

' On récupère la longueur du fichier
LongueurFic = LOF(Fnum)

' On stocke dans une variable le contenu du fichier
PartieFichierLu = Input(LongueurFic, #Fnum)

RechStart = 0
'fermeture du fichier (pas la peine de gaspiller la mémoire)
Close #Fnum

Et voici des extraits de la fonction de recherche (je simplifie car il a
fallut gérer les gros fichiers (découpage en plusieurs parties de la zone à
analyser) et la fonction InStr plantait) :

RechStart = InStr(RechStart + 1, FichierLu, MotACherche,
vbTextCompare)

' Le mot a été trouvé
If RechStart <> 0 Then
...
End If

Voilou

François
Avatar
Francois
Bonjour

C'est clair que si je pouvais envoyer une commande Shell du genre "Explorer
/Chemin fichier /Motàchercher > resultat..txt..." ça serait top...
Mais j'ai une autre idée bourin en tête : stocker dans une base access le
contenu texte de tous les documents de la base... Et créer un prog qui
scrute de tps en tps si le contenu de ces fichiers a bougé. => la recherche
plein texte devient alors une simple requête.

A+

François

"Gloops" a écrit dans le message news:
4176a5c2$0$15154$
Salut,

Je me demande si il n'y aurait pas une troisième voie : faire un appel à
l'explorateur Windows, à l'aide d'un Shell par exemple. ça doit être
plus gourmand en mémoire, mais en temps de développement en revanche ...
________________________________________


Avatar
Quasimodo
Francois wrote on 10/20/2004 :
Bonjour,

Je souhaiterais utiliser dans un programme la recherche plein texte de MS
Explorer afin de trouver dans une série de fichiers certains mots clé. J'ai
pu arriver à ce résultat par programmation, mais ça prends 10 fois plus de
temps que celle d'Explorer (30s contre 3s...)...
Y a t'il une API à utiliser ou un paramètre à envoyer à Explorer via une
commande Shell de manière à ce que ce soit ce moteur de recherche de Windows
qui soit exécuté ?

Merci.

François



bonjour,
si vous utilisez des fichiers de type word, excel, vous pouvez utiliser
le système com de microsoft, propre à office et travailler sur les
propriétés du document. Sinon si vous avez la main mise sur la création
des fichiers, demandez aux users et ou créez un système d'indexation
des fichiers que vous parcourez à l'aide de votre application.
Exemple = un user créer un fichier, l'enregistre dans un folder bien
précis. Votre application scan à interval régulier tout nouveau fichier
créer dans ce folder, l'index en l'ouvrant et en enregistrent toutes
ces données (répertorie le tittre, les propriétés, date de création, de
modification, par qui, ...) dans un fichier type MS Access.
Voila, peut être un début de piste :')

@+Quaz

--
This is an automatic signature of MesNews.
Site : http://mesnews.no-ip.com
Avatar
Francois
Bonjour

C'est un peu la solution de contournement que je pensais faire :

"....Mais j'ai une autre idée bourin en tête : stocker dans une base access
le contenu texte de tous les documents de la base... Et créer un prog qui
scrute de tps en tps si le contenu de ces fichiers a bougé. => la recherche
plein texte devient alors une simple requête."

Ca confirme cette piste et peut être la bonne solution puisqu'effectivement
je sais dans la base où se trouvent ces fichiers.

Merci

François
1 2