Novembre 2024 | Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
---|
| | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | Calendrier |
|
|
| StringList. | |
| | Auteur | Message |
---|
Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Dim 24 Jan 2016 - 13:13 | |
| Bonjour. @Klaus. Le code suivant est beaucoup plus rapide qu'une recherche avec la fonction de recherche dans une StringList. Ne pourrais-tu pas créer une nouvelle fonction de recherche qui ferait la même chose, mais avec une seule ligne d'appel de DLL ? Et là, ce serait vraiment le top ! Le code suivant me donnant toutes les lignes concernées en 1 sec. Merci de la suite. - Code:
-
dll_on "kgf"
dim a$, buf$, c$, crlf$, debut$, f$, i%, k%, longueur%, p%, pattern$, res%, x%, y%, z%
f$="fichiers\formes_verbales_français_anglais_avec_complement.txt" p%=1 pattern$="mange " crlf$=chr$(13)+chr$(10)
res%=dll_call1("OpenBinaryFile",adr(f$))
a$="" debut$=time$
while 0=0 pattern$="mange " res%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(pattern$),p%) if res%=0 then exit_while
z%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(crlf$),res%) buf$=string$(100," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),z%-res%,res%,adr(buf$))
a$=a$+"'"+trim$(buf$)+"'"+crlf$ p%=z%+2 end_while
message debut$+" "+time$+": "+crlf$+a$
res%=dll_call1("CloseBinaryFile",adr(f$)) | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Dim 24 Jan 2016 - 13:26 | |
| Voici une version encore légèrement optimisée: - Code:
-
dll_on "kgf"
dim a$, buf$, c$, crlf$, debut$, f$, i%, k%, longueur%, p%, pattern$, res%, x%, y%, z%
f$="formes_verbales_français_anglais_avec_complement.txt" p%=1 pattern$="mange " crlf$=chr$(13)+chr$(10)
res%=dll_call1("OpenBinaryFile",adr(f$))
a$="" debut$=time$
pattern$="mange " while 0=0 res%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(pattern$),p%) if res%=0 then exit_while
z%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(crlf$),res%) buf$=string$(z%-res%," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),z%-res%,res%,adr(buf$))
a$=a$+"'"+buf$+"'"+crlf$ p%=z%+2 end_while
message debut$+" "+time$ message a$
res%=dll_call1("CloseBinaryFile",adr(f$)) Je vais voir si je peux faire quelque chose, sans casser l'existant. Pas facile ! | |
| | | Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Dim 24 Jan 2016 - 13:45 | |
| Bonjour.
@Klaus.
Je pensais à la création d'une toute nouvelle fonction, ce qui éviterait de casser l'existant.
Merci de la suite. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Dim 24 Jan 2016 - 14:16 | |
| Oui, c'est ce je suis en train de faire. Une copie de la fonction SearchPatternInBinaryFile sous un autre nom, avec deux paramètres supplémentaires: l'adresse du critère de fin (crlf$ dans ton cas) et l'adresse d'une variable recevant la longueur réelle, incluant les critères de début et de fin... | |
| | | Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Dim 24 Jan 2016 - 15:48 | |
| Bonjour.
Merci de ne pas oublier un critère de début (Ex: crlf$)
Exemple ----------
Ligne 18649: alluma la télévision #12403
Dans mon code, je recherche 'la télévision': il faut absolument que la chaîne soit placée en tout début de ligne dans le fichier texte. Donc, le résultat ici doit être zéro, et non 8 !!
Le résultat est donc identique à la recherche avec une StringList, mais en beaucoup plus rapide.
A la limite, il faudrait donc chercher critère de début+chaîne+critère de fin.
Suis-je assez clair ?
Merci de la suite. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Dim 24 Jan 2016 - 16:33 | |
| Ce que je suis en train de faire, c'est une fonction de recherche avec 2 critères: début et fin. On cherche d'abord le critère de début. Si celui-ci est trouvé, on cherche, à partir de cette position, le critère de fin. Si ce dernier est trouvé, on retourne comme résultat toujours la position du début du critère de début, mais à travers un paramètre supplémentaire, on retourne la longueur résultante, du début du critère de début jusqu'à la fin du critère de fin. Ceci permet ensuite de faire une lecture précise du nombre exact de caractères.
Si tu ne veux pas inclure le critère de début dans la lecture, tu additionnes la longueur du critère de début à la position recherchée, et du la soustrais de la longueur retournée. Si tu ne veux pas inclure le critère de fin dans la lecture, tu soustrais simplement sa longueur de la longueur retournée.
Je pense que ça convient comme ça, non ? | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Dim 24 Jan 2016 - 16:48 | |
| C'est mis en ligne. Voilà à quoi ça ressemble: - Code:
-
dll_on "kgf"
dim a$, buf$, c$, crlf$, debut$, f$, i%, k%, longueur%, p%, pattern$, res%, x%, y%, z%
f$="formes_verbales_français_anglais_avec_complement.txt" p%=1 pattern$="mange " crlf$=chr$(13)+chr$(10)
res%=dll_call1("OpenBinaryFile",adr(f$))
a$="" debut$=time$
pattern$="mange " while 0=0 if 1=1 : ' nouvelle version res%=dll_call5("SearchPatternInBinaryFileEx",adr(f$),adr(pattern$),adr(crlf$),p%,adr(longueur%)) if res%=0 then exit_while buf$ = string$(longueur%," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),longueur%,res%,adr(buf$)) a$=a$+"'"+buf$+"'"+crlf$ p% = res% + longueur% end_if if 1=2 : ' ancienne version res%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(pattern$),p%) if res%=0 then exit_while
z%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(crlf$),res%) buf$=string$(z%-res%," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),z%-res%,res%,adr(buf$))
a$=a$+"'"+buf$+"'"+crlf$ p%=z%+2 end_if end_while
message debut$+" "+time$ message a$
res%=dll_call1("CloseBinaryFile",adr(f$)) Le code contient ce qu'il faut pour la version ancienne et la nouvelle version, conditionné par des IF. ainsi, tu peux facilement de passer de l'un à l'autre pour comparer. | |
| | | Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Dim 24 Jan 2016 - 17:03 | |
| Bonjour. @Klaus. OK, merci, c'est presque parfait. J'aurais préféré, en plus, la recherche automatique de la position en arrière d'un critère supplémentaire. Ceci afin de lire automatiquement la chaîne complète entre 2 CRLF. Mais je ne sais pas si cela est possible. Car sinon, cela m'oblige à ajouter le code suivant: - Code:
-
for k%=res% to 1 step -1 if mid$(chaine$,k%,1)=chr$(10) then exit_for next k% Le gain de vitesse gagné avec les fichiers binaires (50% après test), par rapport aux StringList, serait perdu à cause de cette boucle. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Dim 24 Jan 2016 - 17:15 | |
| Je ne comprends pas bien... - Citation :
- lire automatiquement la chaîne complète entre 2 CRLF
La commande FILE_READLN fait exactement ça - tu n'as pas besoin d'une fonction DLL pour ça, non ? Je ne vous pas bien ce que cette demande fait dans ce contexte. A moins que... en effet: si tu cherches "mange ", la première ligne trouvée est en fait "déjeuner|mange avec un lance - pierr #82861". Alors, je te suggère de prendre comme critère de début crlf$+"mange " et comme critère de fin crlf$. Puis, tu additionnes 2 au résultat trouvé et tu soustrais 2 de la longueur retournée? Et voilà - tu as la ligne complète ! | |
| | | Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Dim 24 Jan 2016 - 17:19 | |
| Bonjour.
OK, merci Klaus, je vais opter pour ta solution:
soit chercher la chaîne CRLF$+texte. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Dim 24 Jan 2016 - 17:30 | |
| Comme ça, ça a l'air de marcher: - Code:
-
dll_on "kgf"
dim a$, buf$, c$, crlf$, debut$, f$, i%, k%, longueur%, p%, pattern$, res%, x%, y%, z%
f$="formes_verbales_français_anglais_avec_complement.txt" p%=1 pattern$="mange " crlf$=chr$(13)+chr$(10)
res%=dll_call1("OpenBinaryFile",adr(f$))
a$="" debut$=time$
pattern$=crlf$ + "mange " while 0=0 if 1=1 res%=dll_call5("SearchPatternInBinaryFileEx",adr(f$),adr(pattern$),adr(crlf$),p%,adr(longueur%)) if res%=0 then exit_while res% = res% + 2 buf$ = string$(longueur%," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),longueur%,res%,adr(buf$)) a$=a$+"'"+buf$+"'"+crlf$ p% = res% + longueur% end_if if 1=2 res%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(pattern$),p%) if res%=0 then exit_while
z%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(crlf$),res%) buf$=string$(z%-res%," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),z%-res%,res%,adr(buf$))
a$=a$+"'"+buf$+"'"+crlf$ p%=z%+2 end_if end_while
message debut$+" "+time$ message a$
res%=dll_call1("CloseBinaryFile",adr(f$)) | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Dim 24 Jan 2016 - 19:21 | |
| Oups... il y avait un détail qui clochait... recharge la DLL stp si tu l'as chargée avant 19h19. Et voici comment ça doit marcher: - Code:
-
dll_on "kgf"
dim a$, buf$, c$, crlf$, debut$, f$, i%, k%, longueur%, p%, pattern$, res%, x%, y%, z%
f$="formes_verbales_français_anglais_avec_complement.txt" p%=1 pattern$="mange " crlf$=chr$(13)+chr$(10)
res%=dll_call1("OpenBinaryFile",adr(f$))
a$="" debut$=time$
pattern$ = crlf$ + "mange " while 0=0 if 1=1 res%=dll_call5("SearchPatternInBinaryFileEx",adr(f$),adr(pattern$),adr(crlf$),p%,adr(longueur%)) if res%=0 then exit_while res% = res% + 2 : ' décalage pour ne pas prendre le CRLF du début longueur% = longueur% -2 -2 : ' ne prendre ni le CRLF du début ni celui de la fin buf$ = string$(longueur%," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),longueur%,res%,adr(buf$)) a$=a$+str$(longueur%)+" '"+buf$+"'"+crlf$ p% = res% + longueur% end_if if 1=2 res%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(pattern$),p%) if res%=0 then exit_while
z%=dll_call3("SearchPatternInBinaryFile",adr(f$),adr(crlf$),res%) buf$=string$(z%-res%," ") i%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),z%-res%,res%,adr(buf$))
a$=a$+"'"+buf$+"'"+crlf$ p%=z%+2 end_if end_while
message debut$+" "+time$ message a$
res%=dll_call1("CloseBinaryFile",adr(f$)) Du vois les commentaires pour l'ajustement des deux valeurs res% et longueur% retournées par la fonction, afin de NE PAS copier les CR LF en début ni en fin de ligne ! Car res% donne l'adresse du début du premier critère, et longueur% donne la longueur totale,y compris les deux critères ! | |
| | | Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Lun 25 Jan 2016 - 7:47 | |
| Bonjour.
Merci Klaus, tout fonctionne parfaitement.
Mais on peut aller plus loin, en ajoutant la possibilité de lire la chaîne concernée située entre les deux CRLF, après avoir trouvée la position de la 1ère occurence de la chaîne.
Je vois bien une commande res%=ReadString(...).
Et là, ce serait vraiment une grande avancée.
Je ne peux pas utiliser File_Readln, car le fichier n'a pas été ouvert avec File_Open_Read !
Merci de la suite. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Lun 25 Jan 2016 - 11:20 | |
| Peut-être, Pedro, qu'on pourrait inclure de read dans la fonction. Mais tu perdrais la possibilité de gérer la lecture en incluant ou non, le pattern de début et/ou le pattern de fin. De même, tu ne pourras plus réserver l'espace nécessaire avant la lecture par la fonction string$, ce qui t'oblige à réserver un grand espace avant l'appel, puis de faire un trim$ après. Et tu perds tout avantage de vitesse d'exécution...
Tu vois bien que dans le code de démo, je procède en 3 phases: - recherche de l'information - préparation de la variable recevant les données - lecture directe dans cette variable Difficile d'optimiser mieux, cal malheureusement, je ne peux pas créer une réservation d'une variable chaîne de caractères de Panoramic, à partir de al DLL. | |
| | | Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Lun 25 Jan 2016 - 13:56 | |
| Bonjour. Merci Klaus pour ces précisions. En tout cas, tout fonctionne parfaitement maintenant. Je pensais à l'amélioration de la commande suivante: res%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),longueur%,x%,adr(e$))
Remplacer longueur% par un paramètre par$ correspondant au caractère final de fin de chaîne. On aurait donc: - Code:
-
e$=string$(100," ") par$=crlf$ x%: trouvé auparavant par la fonction SearchPatternInBinaryFile. res%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),par$,x%,adr(e$)) La chaîne serait enregistrée dans e$. | |
| | | Klaus
Nombre de messages : 12331 Age : 75 Localisation : Ile de France Date d'inscription : 29/12/2009
| Sujet: Re: StringList. Lun 25 Jan 2016 - 19:01 | |
| Quelques remarques par rapport à ta suggestion: 1. sur le plan de la syntaxe: - Code:
-
res%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),par$,x%,adr(e$)) n'est pas possible, il faudrait que ce soit: - Code:
-
res%=dll_call4("ReadBlockFromBinaryFileToString",adr(f$),adr(par$),x%,adr(e$)) 2. sur le fond:Je ne vois pas ce que ça change sur le fond. Qu'on passe adr(par$) ou la longueur, il faut déterminer une limite de lecture. Or, les fonctions SearchPatternInBinaryFile et SearchPatternInBinaryFileEx contiennent toute la logique pour chercher une chaîne de caractères dans un fichier binaire, et SearchPatternInBinaryFileEx est même capable de faire cela deux fois dans la foulée. En guise de résultat, ces fonctions renvoient bien sûr une adresse de début, mais pour SearchPatternInBinaryFileEx également une longueur. Alors, greffer une recherche dans la fonction de lecture ne fait que mélanger les genres et n'apporte rien de plus: il faut, dans tous les cas, faire 2 appels: - soit SearchPatternInBinaryFile suivi de la fonction de lecture modifiée - soit SearchPatternInBinaryFileEx suivi de la fonction de lecture telle qu'elle est. Donc, je préfère rester avec une séparation logique cohérente du travail à effectuer: - les fonctions SearchPatternInBinaryFile et SearchPatternInBinaryFileEx se chargent de déterminer les limites - la fonction ReadBlockFromBinaryFileToString lit le texte délimité dans une chaîne. | |
| | | Pedro
Nombre de messages : 1596 Date d'inscription : 19/01/2014
| Sujet: StringList. Lun 25 Jan 2016 - 20:50 | |
| Bonsoir.
Bien Klaus, je suis ton raisonnement. D'ailleurs, ces fonctions sont déjà bien plus rapides que la fonction de recherche dans un objet liste. Ce qui me convient très bien. | |
| | | Contenu sponsorisé
| Sujet: Re: StringList. | |
| |
| | | | StringList. | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |