[..] Problème Parser fichier Mail - le retour

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
soloflight
Niveau 1
Niveau 1
Messages : 9
Enregistré le : mer. 13 juil. 2011 11:43
Status : Hors ligne

[..] Problème Parser fichier Mail - le retour

#1

Message par soloflight »

Bonsoir à tous,

Les vacances sont finies et les problématiques de script reviennent ;-)

J'ai déjà réalisé précédemment en petit parser de fichier HTML pour retrouver du code dans une page et je souhaite aujourd'hui étendre ce mode de recherche sur un fichier de message Mail issu de thunderbird (le fichier fait 16 Mo, mais peut monter jusqu'à 100 Mo).

Mon script aujourd'hui consiste juste à trouver le numéro de ligne du fichier qui marque le début de chaque message : un ligne commençant par 'From -' et à noter ces numéros de ligne dans un fichier.

Voici le code

Code : Tout sélectionner

#Include <File.au3>
#include<Array.au3>

$fichier = "Inbox"
$nbr_lignes = _FileCountLines($fichier)

MsgBox(0, "Comptage",$nbr_lignes )


$fp = FileOpen($fichier, 0) ; on ouvre le fichier Inbox
$file = FileOpen("result.txt", 1) ; on ouvre le fichier result.txt

$contenu = ""               ;mise à zéro de la variable contenu
$nbr_messages = 0
$index_debut_mail = 0
For $i = 1 To $nbr_lignes

    $contenu = ""

    $lignesX = FileReadLine($fp, $i)

    $trouve = StringInStr($lignesX,"From -",1) ; on cherche la chaine  "From -"



       if $trouve <> 0 Then ; quand on la trouve c'est qu'on a la ligne avec la valeur que l'on cherche cherche

        $index_debut_mail = $i
        $nbr_messages = $nbr_messages + 1



        ;Check if file opened for writing OK
        If $file = -1 Then
            MsgBox(0, "Error", "Unable to open file.")
            Exit
        EndIf

        FileWriteLine($file, $index_debut_mail & @CRLF)




    EndIf
Next

MsgBox(0, "Fin de programme","il y a "&$nbr_messages&" dans le fichier traité" )
MsgBox(0, "Fin de programme","le programme est terminé" )



FileClose($fp)
FileClose($file)
 
Mes problème sont les suivants :

Autant la lecture du nombre de ligne du fichier est très rapide (240 000 lignes) en 3 sec, mais ensuite le parsing est lent et come le temps d'éxécution est long, le script 'pause'.
j'arrive à peine à traiter 21 000 lignes.

j'utilise pourtant les file handle pour FileOpen, je me demande ou se situe le souci (peut être une limitation que je ne connais pas...)

question subsidiaire : avec les file handle, le fichier à traiter est il chargé intégralement en mémoire ou bien traité plutôt comme un flux ?

Merci pour votre aide et vos lumières
Modifié en dernier par soloflight le mar. 06 sept. 2011 15:21, modifié 2 fois.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Problème Parser fichier Mail

#2

Message par mikell »

Peut-être ce script serait plus rapide (mais 240000 lignes, c'est quand même long)
► Afficher le texte
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
soloflight
Niveau 1
Niveau 1
Messages : 9
Enregistré le : mer. 13 juil. 2011 11:43
Status : Hors ligne

Re: [..] Problème Parser fichier Mail

#3

Message par soloflight »

Merci Mikell,

Le temps de traitement est parfait (5 sec) et la msgbox affiche bien 234 messages, mais ce que je souhaite écrire dans le fichier result c'est le numéro de chaque ligne ou l'on a détecté la chaîne 'From -'.

dans votre version "vous" écrivez 216 lignes avec un 1 pour le premier message (car il effectivement le message 2 commence à la ligne 217).

pouvez vous aussi me préciser le sens de la syntaxe &= dans :

Code : Tout sélectionner

$txt &= $index_debut_mail & @CRLF
Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11830
Enregistré le : ven. 20 juil. 2007 21:00
Localisation : Bordeaux
Status : Hors ligne

Re: [..] Problème Parser fichier Mail

#4

Message par Tlem »

Remplacez

Code : Tout sélectionner

If StringLeft($lignesX, 6) = "From -" Then $index_debut_mail +=1
   ; If StringInStr($lignesX,"From -",1) Then $index_debut_mail +=1
    $txt &= $index_debut_mail & @CRLF
par

Code : Tout sélectionner

If StringLeft($lignesX, 6) = "From -" Then 
    $index_debut_mail +=1
    $txt &= $index_debut_mail & @CRLF
EndIf

Code : Tout sélectionner

$txt &= $index_debut_mail & @CRLF
revient à écrire

Code : Tout sélectionner

$txt = $txt & $index_debut_mail & @CRLF
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Problème Parser fichier Mail

#5

Message par mikell »

Moui désolé j'étais un peu pressé hier soir...
M'enfin bon Tlem a compris l'intention et a rectifié c'est le principal Image
► Afficher le texte
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
soloflight
Niveau 1
Niveau 1
Messages : 9
Enregistré le : mer. 13 juil. 2011 11:43
Status : Hors ligne

Re: [R] Problème Parser fichier Mail

#6

Message par soloflight »

Merci à tous les deux pour votre réponse rapide, en cherchant je suis arriver à la même conclusion sur le EndIF ;-)

merci aussi pour le petit cours accéléré de syntaxe.

j'édite le post et je passe à [R]
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [R] Problème Parser fichier Mail

#7

Message par mikell »

Dernier détail, si vous voulez afficher une barre de progression pendant le traitement alors votre solution du début avec _FileCountLines et une boucle For est la bonne
Simplement, pour conserver la rapidité veillez à ce que les 2 fichiers soient ouverts successivement, à préférer StringLeft à StringInStr, et à optimiser le nombre de variables Image
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
soloflight
Niveau 1
Niveau 1
Messages : 9
Enregistré le : mer. 13 juil. 2011 11:43
Status : Hors ligne

Re: [..] Problème Parser fichier Mail - le retour

#8

Message par soloflight »

Je reviens vers vous avec toujours mon script de parsing.

Mon souci est le suivant :

j'écris le script pour tester le process, tout va bien l'intégralité des taches unitaires se déroule sans souci :

1°) compter le nombre de messages dans le fichier
2°) mémoriser les index des lignes de début de message
3°) copier chaque message dans un tableau dédié
4°) parser le message à la recherche des infos
5°) écrire le résultat dans un fichier

Le problème vient quand je met tout cela dans une boucle (avec comme compteur le nombre de message).

j'ai fait un test manuel, le script s'éxécute en un temps à peu près correct pour 25 messages, mais dès que je met 30... et mon plus gros fichier à plus de 1000 messages

voilà le code

Code : Tout sélectionner

#Include <File.au3>
#include<Array.au3>

$result = FileOpen ("result_durnod_gmail.txt")
if $result <> -1 then FileDelete ("result_durnod_gmail.txt")

$extraction = FileOpen("extraction_durnod_gmail.txt")
if $extraction <> -1 then FileDelete ("extraction_durnod_gmail.txt")

Global $fichier = "C:\Users\EUREKA\AppData\Roaming\Thunderbird\Profiles\8mwyw99c.default\ImapMail\imap.googlemail-3.com\Inbox"
Global $txt = ""
Global $index_debut_mail = 0
Global $no_ligne = 0
Global $nbr_messages = 0

$fp = FileOpen($fichier, 0) ; on ouvre le fichier Inbox

;--------------------- On détermine le nombre de messages dans le fichier et l'index du début de chaque message-------------

While 1

    $lignesX = FileReadLine($fp)
    $no_ligne +=1
    If @error = -1 Then ExitLoop
    If StringLeft($lignesX, 6) = "From -" Then
        $index_debut_mail = $no_ligne
        $txt &= $index_debut_mail & @CRLF
    EndIf


Wend

FileClose($fp)



$file = FileOpen("result_durnod_gmail.txt", 1) ; on ouvre le fichier result.txt
FileWrite($file, $txt)                          ; on écrit les données
FileClose($file)                                ; on ferme le fichier

$fichier_resultat = "result_durnod_gmail.txt"

Global $nbr_messages = _FileCountLines($fichier_resultat) ; on compte le nombre de messages pour créer le tableau des index

Dim $index_debut_message[$nbr_messages]; on crée le tableau qui contient les n° de lignes de début de chaque message

$fp_resultat =  FileOpen($fichier_resultat, 0) ; on ouvre le fichier résultat pour lire chaque ligne

$i = 0

While 1 ; boucle pour remplir le tableau des index de début de message

    $lignesY = FileReadLine($fp_resultat)
    If @error = -1 Then ExitLoop
    $index_debut_message[$i]=$lignesY
    $i += 1


Wend

;----------------------------------on va extraire chaque message dans un tableau pour le parser-----------------------------

Global $n = 0

$txt =""

for $m = 1 to $nbr_messages ; boucle pour traiter le nombre de message du fichier

$fp = FileOpen($fichier, 0) ; on ouvre le fichier Inbox

Global $taille_message = 0

$taille_message = $index_debut_message[$n+1]-$index_debut_message[$n] ;on affecte une valeur de taille de message pour la suite

Dim $Array_message[$taille_message]; on crée le tableau qui va contenir chaque message

$k = 0

for $j= 1 to $taille_message                    ;on repmli le tableau avec le message

    $compteur = $index_debut_message[$n]+ $k
    $lignesZ = FileReadLine($fp,$compteur)
    $Array_message[$k]=$lignesZ
    $k += 1
Next



Global $champ_From = 0      ; on prépare les variables pour stocker le résultat du parsing
Global $champ_Subject = 0

$i = 0
$l = 0


    For $i= 1 to $taille_message ; on parse le tableau du message pour trouver les valeurs From: et Subject:

        $lignes_message = $Array_message[$l]
        If StringLeft($lignes_message, 5) = "From:" Then $champ_From = $Array_message[$l]
        If StringLeft($lignes_message, 8) = "Subject:" Then $champ_Subject = $Array_message[$l]
        $l += 1
    next


$txt &= $champ_From &" ; "& $champ_Subject & @CRLF

$n += 1
FileClose($fp)

Next



$file = FileOpen("extraction_durnod_gmail.txt", 1) ; on ouvre le fichier de résultat de l'extraction
FileWrite($file, $txt)                              ; on écrit
FileClose($file)                                    ; on ferme le fichier résultat
FileClose($fp)                                      ; on ferme le fichier Inbox qui était resté ouvert



MsgBox(0, "Fin de programme","il y a "& $nbr_messages &" messages dans le fichier traité" )
MsgBox(0, "Fin de programme","le programme est terminé" )
deepfirejet
Niveau 1
Niveau 1
Messages : 11
Enregistré le : lun. 05 sept. 2011 10:59
Status : Hors ligne

Re: [..] Problème Parser fichier Mail

#9

Message par deepfirejet »

Code : Tout sélectionner

$txt &= $index_debut_mail & @CRLF
revient à écrire

Code : Tout sélectionner

$txt = $txt & $index_debut_mail & @CRLF
Désolé de m'immiscer dans la conversation mais dois-je comprendre que la syntaxe $a = $a & "xxx" est plus rapide que $a &= "xxx" ? Dans ce cas quelle est l'utilité de &= ?
Avatar du membre
timmalos
Niveau 11
Niveau 11
Messages : 1970
Enregistré le : dim. 18 mai 2008 15:16
Status : Hors ligne

Re: [..] Problème Parser fichier Mail - le retour

#10

Message par timmalos »

Code : Tout sélectionner

$t = ""
$t1 = TimerInit()
For $i = 1 to 100000
    $t = $t & "R"
Next
MsgBox(0,"",TimerDiff($t1))

$t = ""
$t1 = TimerInit()
For $i = 1 to 100000
    $t &= "R"
Next
MsgBox(0,"",TimerDiff($t1))

 
Vous verrez que '&=' est beaucoup plus rapide que l'autre syntaxe, en plus d'être plus rapide à écrire ;)
Tlem signifiait seulement à ceux qui ne le sauraient pas que les 2 syntaxes revenaient au même.
deepfirejet
Niveau 1
Niveau 1
Messages : 11
Enregistré le : lun. 05 sept. 2011 10:59
Status : Hors ligne

Re: [..] Problème Parser fichier Mail - le retour

#11

Message par deepfirejet »

Ouf. Je peux donc conserver mes habitude. :)
soloflight
Niveau 1
Niveau 1
Messages : 9
Enregistré le : mer. 13 juil. 2011 11:43
Status : Hors ligne

Re: [..] Problème Parser fichier Mail - le retour

#12

Message par soloflight »

un petit UP sur mon message, un problème de performance sur un gros fichier..

merci pour votre aide
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..] Problème Parser fichier Mail - le retour

#13

Message par mikell »

J'ai soudain un énorme doute Image
Serait-il possible d'avoir un bout de votre fichier Inbox de départ, au format texte (avec les 4 ou 5 premiers messages) ? Le but est de savoir si à la fin de chaque message ça enchaine imédiatement sur la balise From du message suivant, et j'aimerais faire un chtit test...

EDIT
En fait ce que j'aimerais tester c'est ça :
► Afficher le texte
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Répondre