Page 1 sur 2

Pb lecture ?

Publié : lun. 15/mai/2006 22:42
par Jeff
Bonjour,

Tout d'abord bonjour à tous, je débute sous PB et c'est drôle j'ai dès le départ un PB :)

Lorsque j'essaye de lire un fichier de type Txt, le programme semble tourner en rond, ce qui est confirmé je visualise les infos lues avec Debug

J'utilise le code ci-après

Code : Tout sélectionner

 If ReadFile(0, "c:\test\test.asc")  ; Lecture du fichier 
    While Eof(0) = 0           ; Boucle tant que la fin du fichier n'est pas atteinte
        Debug ReadString(0)
     Wend
    CloseFile(0)               ; Ferme le fichier précédemment ouvert
  Else
    MessageRequester("Information","Impossible d'ouvrir le fichier!")
  EndIf

L'utilisation processeur monte à 100%...

Quelqu'un a des idées ?

Merci d'avance

Publié : lun. 15/mai/2006 23:27
par flaith
Salut et bienvenue :D

n'as-tu pas oublié de cocher le mode debug, car sans ca j'ai la même chose aussi :wink:

Publié : mar. 16/mai/2006 20:59
par Jeff
L'option debogeur est bien cochée.

J'ai modifié le code pour ne lire que les 1 000 premières lignes et ça marche !!

Code : Tout sélectionner

 If ReadFile(0, "c:\test\test.asc")  ; Lecture du fichier 
    i=0
    While i<1000 ;Eof(0) = 0           
        Debug Str(i)+"    "+ReadString(0)
       i=i+1
       
    Wend
    CloseFile(0)               
  Else
    MessageRequester("Information","Impossible d'ouvrir le fichier!")
  EndIf



Je ne comprends pas d'où vient le pb (fichier, limitation PB ???)

Pour un début ça commence bien :?:

Publié : mar. 16/mai/2006 21:11
par Jeff
Je viens de me rendre compte que le fichier a environs 79 500 lignes.

Y-a-il un rapport ? sachant que pour mon application ce n'est pas énorme.

J'ai visualé le fichier avec l'IDE de PB plus de 30 secondes pour l'ouvrir alors qu'avec le bloc note c'est presque immédiat.

Pour les fichiers de grandes tailles, y-a-t-il une procédure spéciale ?

Faut-il faire une lecture par caractère ? Je vais essayer...

Publié : mar. 16/mai/2006 21:41
par Jeff
J'ai trouvé, il fallait copier le fichier en mémoire puis le recopier d'un bloc. :lol:

Publié : mar. 16/mai/2006 22:51
par flaith
Jeff a écrit :Je viens de me rendre compte que le fichier a environs 79 500 lignes...
8O afficher ce nombre de lignes surtout en mode debug, je comprends mieux pourquoi c'est aussi long :wink: et, effectivement, il faut lire le fichier en mémoire et ensuite l'afficher :)

Publié : mer. 17/mai/2006 0:07
par Flype
ou bien, avec PB4, pour aller plus vite on peut changer le buffer de lecture.

avec FileBuffersSize(#Fichier, Taille)

par défaut il est fixé à 4096 octets.

Publié : mer. 17/mai/2006 16:01
par KarLKoX
Comme l'a dit Flype, il faut faire attention à la taille du cache, j'en ai fait les frais car je ne comprenais pas pourquoi je n'arrivais jamais à lire le nombre d'octet demandé, il m'a fallut baisser la taille du cache à ... 32 octets !

Publié : ven. 19/mai/2006 21:14
par Jeff
J'ai tenu de vos remarques, désormais lorsque j'ouvre un fichier en local pas de problème. Par contre lorsque j'essaye d'ouvrir le même fichier sur un serveur interne j'ai toujours le même message d'erreur.

Le code MAJ est le suivant :

Code : Tout sélectionner

If file$
          timer1= ElapsedMilliseconds() 
 
          If ReadFile(0, file$)  ; Lecture du fichier 

               FileBuffersSize(0,512)      
               length = Lof(0)                                                                  ; Lit la taille en octets du fichier 
       
       
               *MemoryID = AllocateMemory(length)                               ; alloue un bloc mémoire de la taille du fichier
               If *MemoryID
                    bytes = ReadData(0, *MemoryID, length)                        ; Lit les données du fichier et les place dans le bloc mémoire
                    AddGadgetItem(0, -1, PeekS(*MemoryID))                      ; Ajoute le bloc mémoire au gadget
                    FreeMemory(*MemoryID)        
                    SetGadgetState   (1, 50)                                      ; On libère la mémoire
               EndIf
    
               CloseFile(0)                                                                     ; Ferme le fichier précédemment ouvert
 
               timer2= ElapsedMilliseconds()
               timer3 = timer2 - timer1
               TextGadget(2, 145, 250,350,20,"Temps de chargement du fichier (millisecs) : "+Str(timer3))
    
           Else
               MessageRequester("Information","Impossible d'ouvrir le fichier!")
          EndIf

     EndIf

A noter le fichier à traiter fait 54 Mo et contient 727 000 lignes (temps ouverture 10 secondes)

Est-il possible de connaître la cause de l'erreur ? A noter que si j'ouvre le fichier avec le notepad sur le serveur pas de pb !! C'est rageant !

J'ai fait également des tests en changeant la taille du buffer (32, 512...) aucun effet.

Je bute sur ce problème pour mon application et je ne sais plus par quel bout le prendre !!!

Si quelqu'un peut m'aider.

@+

Publié : ven. 19/mai/2006 21:54
par Flype
on va essayer de t'aider, jeff :wink:

déjà dis moi juste ton fichier c'est de l'ascii ou de l'unicode ?

tu utilises un chemin de fichier du genre '//monpc/shareddocs/fichier.txt' ?

Publié : ven. 19/mai/2006 22:06
par Jeff
Le fichier est un fichier ASCII (sauf erreur de ma part)

Pour le chemin du fichier j'ouvre au préalable une fenêtre avec la commande suivante:

Code : Tout sélectionner

   file$ = OpenFileRequester("Select a file","","Text (.txt)|*.txt;*.asc|All files (*.*)|*.*",0)
JF

Publié : ven. 19/mai/2006 22:18
par Dorian
HS: il est simpa ton avatar ^^

Bon sinon tu as essayé de mettre des debug un peu partout dans ton code pour voir où sa bug ?

Publié : ven. 19/mai/2006 22:55
par Backup
Dorian a écrit :HS: il est simpa ton avatar ^^
c'etait celui de Comtois dans le temps ! :lol: :lol:

Publié : ven. 19/mai/2006 23:13
par Le Soldat Inconnu
Bon, je pense avoir la raison, un string ne peut pas dépasser 65000 octet environ
donc avec PeekS(*MemoryID) sur une taille de 54mo, ca passe pas, forcément
Il faut que tu découpes ligne à ligne

Pour accéler l'affichage, masque simplement le gadget pendant son remplissage, et affiche le après.

Code : Tout sélectionner

HideGadget(....)

Publié : ven. 19/mai/2006 23:17
par Flype
est-ce que le code suivant fonctionne ?

j'ai essayé chez moi en fabricant un fichier de texte de 30mo.
stocké ailleurs sur le réseau... et çà fonctionne :wink:

remplace juste la première ligne par ton chemin de fichier.

par contre, c'est très bas niveau comme programmation.
là on passe par l'api windows qui semble effectivement plus enclin à lire des fichiers UNC ( \\server\folder\file ) que le ReadFile() de PureBasic.

donc bienvenue dans les joies de la programmation win32.

Code : Tout sélectionner

FileName.s = "\\server\folder\file.txt"

Procedure.l ReadFileInMemory(FileName.s)
  
  Protected hFile.l, BufPtr.l, BufRead.l, BufSize.q
  
  hFile = CreateFile_(FileName, #GENERIC_READ, #FILE_SHARE_READ, #Null, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL, #Null)
  
  If hFile
    
    Debug "Fichier ouvert."
    
    If GetFileSizeEx_(hFile, @BufSize)
      
      Debug "Taille Mémoire: " + StrQ(BufSize)
      
      BufPtr.l = AllocateMemory(BufSize)
      
      If BufPtr
        
        Debug "Mémoire allouée."
        
        If ReadFile_(hFile, BufPtr, BufSize, @BufRead, #Null)
          
          Debug "Nb octets lu: " + Str(BufRead)
          
        Else
          
          Debug "Fichier non-lu: " + Str(GetLastError_())
          
        EndIf
        
      EndIf
      
    EndIf
    
    CloseHandle_(hFile)
    
    ProcedureReturn BufPtr
    
  EndIf
  
EndProcedure

MemoryID.l = ReadFileInMemory(FileName)

If MemoryID
  Debug "Taille Mémoire: " + Str(MemorySize(MemoryID))
  Debug PeekS(MemoryID, 256)
EndIf