Lecture de fichier ligne à ligne

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

OOps, j'avais pas vu ton message de mercredi !!! Dsl ! :?

J'essaie de faire un programme (Moebius) que je comprends, que le public pourrait comprendre, que je n'ai aucun de mal à porter entre Linux, Windows & MacOs, que je n'ai aucun mal à faire évoluer. Et avec tout ca, j'essaie de le faire rapide. A l'heure actuelle, j'ai rempli quatre des premiers points, manque plus que le dernier !

Donc, j'ai peur du trop trash... Mais bon, si il faut refaire une fonction de facon à refaire la facon dont il est pensé, pas de prblème, tant que ca reste compréhensible !
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

En prenant une douche,j'ai compris une de tes idées géniales. Comme quoi ? Par contre, en en sortant une abbération est apparue. lol

Pour la fonction suivante, si je lis charactère à charactère le fichier, aurais je un gain de temps ? Car avant je lisais ligne à ligne et gain de temps, il n'y en avait pas.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Ollivier a écrit :

Code : Tout sélectionner

#FileOpened   = 1
#MemAllocated = 2
#FileLoaded   = 4
#TableCreated = 8

Structure BuildArrayInfo

   FileName.S
   ExecStatus.I

   *SeqBegin
   *SeqEnd
   SeqSize.I ; En octet

   *ArrayTable
   *ArrayTableEnd
   ArrayTableSize.I ; (nombre de pointeurs)

   LineMeanLength.I ; Taille moyenne d'une ligne
   
EndStructure

Structure TextLineInfo
   TextLine.S[1 << 24]
EndStructure

Procedure.L LoadStringArray(*Info.BuildArrayInfo)

   Protected *SeqBegin
   Protected *SeqEnd
   Protected *TextLine
   Protected *TableEnd 
   Protected FileHnd.I
   Protected ExecStatus.I
   
   FileHnd = OpenFile(#PB_Any, *Info\FileName)
   If FileHnd
      
      ExecStatus | #FileOpened
      SeqSize.Q = Lof(FileHnd)
      *SeqBegin = AllocateMemory(SeqSize)
      
      If *SeqBegin
      
         ExecStatus | #MemAllocated
         *SeqEnd = *SeqBegin + SeqSize - 1
      
         If ReadData(FileHnd, *SeqBegin, SeqSize)
         
            ExecStatus | #FileLoaded
            CloseFile(FileHnd)
   
            *Info\SeqBegin = *SeqBegin
            *Info\SeqEnd = *SeqEnd
   
            If *Info\LineMeanLength = 0
               *Info\LineMeanLength = 10 ; Moyenne par défaut
            EndIf
   
            *Info\ArrayTableSize = ((*SeqEnd - *SeqBegin) / *Info\LineMeanLength) << 2
            Debug *Info\ArrayTableSize
            If *Info\ArrayTableSize < 1 << 8
               *Info\ArrayTableSize = 1 << 8
            EndIf
   
            ;Debug *Info\ArrayTableSize
            *Info\ArrayTable = AllocateMemory(*Info\ArrayTableSize)
            If *Info\ArrayTable

               ExecStatus | #TableCreated
               *TextLine = *Info\ArrayTable
               ! mov eax, 13            
               ! mov edi, [p.p_SeqBegin]
               ! mov ebp, [p.p_SeqEnd]
               ! mov edx, [p.p_TextLine]
   
               ! mov ecx, ebp ; ecx = EndSeq
               ! sub ecx, edi ;     - BeginSeq
               ! inc ecx      ;     + 1
LoadStringArrayLoop:
               ! mov ebx, edi ; Retient le début de la chaîne
               ! cld          ; Fixe le sens croissant (convention)
               ! repne scasb  ; Recherche le 13
   
               ! mov byte [edi - 1], 0 ; Remplace le 13 par le 0
               ! inc edi      ; Passe le 10
   
               ! mov [edx], ebx ; Copie l'adresse de début de ligne
               ! add edx, 4 ; ... Et passe au pointeur suivant
   
               ! cmp edi, ebp ; Fin de séquence ?
               ! jng l_loadstringarrayloop ; Non, continue
   
               ! mov [p.p_TableEnd], edx
               *Info\ArrayTableEnd = *TableEnd
               *Info\ArrayTableSize = *TableEnd - *TextLine
               ;Debug "***" + Str(*Info\ArrayTableSize)
               *Info\ArrayTable = ReAllocateMemory(*TextLine, *Info\ArrayTableSize)
            EndIf
         EndIf            
      EndIf
   EndIf
   *Info\ExecStatus = ExecStatus
EndProcedure 

   Define *TextLine.TextLineInfo
   Define BuildArrayInfo.BuildArrayInfo
   
   ;___________________________________________________
   X.S = "Voici le Bonjour" + Chr(13) + Chr(10) + "Ici, et bien c'est le Au revoir" + Chr(13) + Chr(10) + "Et là, ben c'est simplement A bientôt" + Chr(13) + Chr(10)
   CreateFile(0, "Test.TXT")
   For I = 0 To 5000000
      WriteData(0, @X, Len(X) )
   Next
   CloseFile(0)
   Delay(500)
   ;¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
   
   BuildArrayInfo\LineMeanLength = 20
   BuildArrayInfo\FileName = "Test.TXT"
   LoadStringArray(BuildArrayInfo)

   *TextLine = BuildArrayInfo\ArrayTable
   Debug *TextLine\TextLine[0]
   Debug *TextLine\TextLine[1]
   Debug *TextLine\TextLine[2]
   Debug *TextLine\TextLine[BuildArrayInfo\ArrayTableSize >> 2 - 1]
   Debug T1 - T0
   
Re ollivier, actuellement, ce code marche simplement avec des fins de lignes Windows, mais pas des fins de ligne Linux ou MacOs... Suis en train d'essayer de modifier le code, mais je le casse plus que je ne le réussis.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@Progi1984

Tu n'aurais pas un schéma fonctionnel de ton programme? ça serait plus cool en fait!

Sinon, pour rendre compatible le truc voici l'extrait essentiel à la modification.

Code : Tout sélectionner

! mov eax, 13 ; MODIFICATION 1/2
               ! mov edi, [p.p_SeqBegin]
               ! mov ebp, [p.p_SeqEnd]
               ! mov edx, [p.p_TextLine]
   
               ! mov ecx, ebp ; ecx = EndSeq
               ! sub ecx, edi ;     - BeginSeq
               ! inc ecx      ;     + 1
LoadStringArrayLoop:
               ! mov ebx, edi ; Retient le début de la chaîne
               ! cld          ; Fixe le sens croissant (convention)
               ! repne scasb  ; Recherche le 13
   
               ! mov byte [edi - 1], 0 ; Remplace le 13 par le 0
               ! inc edi      ; Passe le 10 ; MODIFICATION 2/2
Il y a uniquement 2 modifs à faire. J'ai commenté les deux seules lignes à modifier.

Code : Tout sélectionner

! mov eax, 13
ça c'est l'endroit où l'on indique le numéro ASCII du premier caractères de fin de ligne. (ici, ça signifie que eax = 13)
Par exemple:
13, 10 on mettra 13
13 tout seul, on mettra 13
10 tout seul, on mettra 10
10, 13, on mettra 10
42, 20, on mettra 42, etc...

Code : Tout sélectionner

! inc edi
ça c'est la deuxième modif. Ici, ça signifie que edi = edi + 1
Si tu as deux caractères de fin, ben c'est bien, ça ne change pas. Si tu n'as qu'un caractère de fin (13 tout seul ou 10 tout seul), ben il faut supprimer cette ligne!!!

Par contre, cette procédure ne fonctionne qu'en ASCII 8 bits. Je ne sais pas ce qu'il en est pour les autres OS: sont-ils forcément en 8bits par caractère?

Ollivier

PS: Désolé pour le retard.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Le process que je veux utiliser est le même que celui qui charge et trie le fichier texte. Par contre, la recherche caractère par caractère ne sert que pour trouver le premier caractère d'une expression. Pour vérifier toute l'expression, on va faire entrer quelques instructions SSE. Connais pas ce truc mais ça déchire un max.

Il me faut absolument quelque chose de clair (carthésien) point de vue compréhension de l'algo. Notamment sur le fait que tu décommentes les lignes à un moment donné: est-ce que tu peux m'expliquer le processus? J'ai l'impression qu'il y a un risque d'erreur dans certains cas. Maintenant, je peux me tromper! Mais il faut réussir à m'enlever ce doute, parce que, moi je vois les commentaires et les dialogues entre guillemets comme une bête noire à dégager avant tout type de recherche. Donc si je te ponds un algo qui te saute des infos importantes, tu ne vas pas être content du tout!

Ollivier
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Désolé, mais finalement, j'ai rentré toutes les lignes dans une liste chainée en utilisant toujours ta fonction de lecture de fichier, ce qui me permet de construire un fichier de 180 000 lignes en deux minutes.
Répondre