fread et fwrite inspirés du C

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

fread et fwrite inspirés du C

Message par Dr. Dri »

Je sais pas ce que j'ai en ce moment avec les pointeurs mais ils me plaisent plus que d'habitude, et j'arrête pas de leur chercher chaque fois une nouvelle utilité, donc j'ai eu l'idée de lire dans un fichier le type qu'on voulai (à part peut être une chaine de caracteres au sens strict, c'est a dire "null terminated" dont on ne connai pas la taille dans le fichier). Ce code s'adresse surtout aux structures et je demande à ceux qui s'y connaissent pour me dire comment savoir si un fichier est ouvert, car je suis passé par usefile mais i le fichier n'est pas ouvert le compilateur génere une erreur (en mode test avec F5 en tout cas). Toute remarque sur une partie du code qui manquerai de logique est aussi la bienvenue.

Voila donc les deux fonctions intéressées (que j'ai mises dans un fichier que j'ai appellé file.pb pour les tests)

Code : Tout sélectionner

Procedure fwrite(buffer.l, size.b, count.b, file.l)
  If buffer=0 Or count<1 Or size<1 Or UseFile(file)=0
    ProcedureReturn 0
  EndIf
  WriteData(buffer, size*count)
  ProcedureReturn 1
EndProcedure

Procedure fread(buffer.l, size.b, count.b, file.l)
  If buffer=0 Or count<1 Or size<1 Or UseFile(file)=0
    ProcedureReturn 0
  EndIf
  If Lof()-Loc()<(size*count)
    ProcedureReturn 0
  EndIf
  ReadData(buffer, size*count)
  ProcedureReturn 1
EndProcedure
Et maintenant deux exemples d'utilisation à utiliser dans l'ordre écrire puis lire (enfin ca va sans dire... de toute facon j'ai essayé de faire une gestion des erreurs)

Code : Tout sélectionner

IncludeFile("file.pb")

Structure bidon
  long.l
  word.w
  byte.b
EndStructure

tabsize = 5

Dim tab.bidon(tabsize-1)
;en C "bidon tab[tabsize];" irai de 0 à tabsize-1

;on rempli le tableau pour avoir des données
For i=0 To tabsize-1
  tab(i)\long = 4 * i
  tab(i)\word = 2 * i
  tab(i)\byte = 1 * i
Next i

If OpenFile(0, "bidon.dat")
  fwrite(@tab(0), SizeOf(bidon), tabsize, 0)
  CloseFile(0)
EndIf

;on prend soin de garder le résultat histoire de comparer
For i=0 To tabsize-1
  Debug tab(i)\long
  Debug tab(i)\word
  Debug tab(i)\byte
  Debug " "
Next i

Code : Tout sélectionner

IncludeFile("file.pb")

Structure bidon
  long.l
  word.w
  byte.b
EndStructure

tabsize = 5

Dim tab.bidon(tabsize-1)
;en C "bidon tab[tabsize];" irai de 0 à tabsize-1

;on ne rempli pas le tableau cette fois...

If OpenFile(0, "bidon.dat")
  fread(@tab(0), SizeOf(bidon), tabsize, 0)
  CloseFile(0)
EndIf

;on peut désormais comparer avec l'écriture
For i=0 To tabsize-1
  Debug tab(i)\long
  Debug tab(i)\word
  Debug tab(i)\byte
  Debug " "
Next i
En fait je vais peut être me faire deux fichiers stdlib.pb et stdio.pb avec ce que je programme en ce moment et puis pour rester dans la logique des noms de fonction PB je les renommerai FileRead et FileWrite.

Dri 0X
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

J'ai voulu faire un exemple d'utilisation un peu plus parlant...
Alors j'ai codé cette fonction :

Code : Tout sélectionner

Procedure LoadBitmap24(Image, Filename$)

  FileHeader.BitmapFileHeader
  InfoHeader.BitmapInfoHeader

  File.l = ReadFile(#PB_Any, Filename$)
  
  If File=0 : ProcedureReturn 0 : EndIf
  
  If FileRead(@FileHeader, SizeOf(BitmapFileHeader), 1, File)=0
    CloseFile(File)
    ProcedureReturn 0
  EndIf
  If FileHeader\bfType<>19778 Or FileHeader\bfSize<>Lof()
    ProcedureReturn 0
  EndIf
  
  If FileRead(@InfoHeader, SizeOf(BitmapInfoHeader), 1, File)=0
    CloseFile(File)
    ProcedureReturn 0
  EndIf
  If InfoHeader\biSize<>40 Or InfoHeader\biCompression<>0 Or InfoHeader\biBitCount<>24
    CloseFile(File)
    ProcedureReturn 0
  EndIf
  
  pImage.l = AllocateMemory(InfoHeader\biSizeImage)
  FileSeek(FileHeader\bfOffBits)
  If pImage=0 Or FileRead(pImage, InfoHeader\biSizeImage, 1, File)=0
    CloseFile(File)
    ProcedureReturn 0
  EndIf
  
  Image = CreateImage(#PB_Any, InfoHeader\biWidth, InfoHeader\biHeight)
  If UseImage(Image)=0
    CloseFile(File)
    ProcedureReturn 0
  EndIf
  
  biPitch = InfoHeader\biWidth * InfoHeader\biBitCount / 8
  biPitch + biPitch % 4
  
  If StartDrawing(ImageOutput())
  
    DefType.l bgr, rgb
    pLine = pImage
    For y=InfoHeader\biHeight-1 To 0 Step -1
      pPixel = pLine
      For x=0 To InfoHeader\biWidth-1
          
        CopyMemory(pPixel, @bgr, 3)
        rgb = (bgr>>16) | ((bgr>>8&255)<<8) | ((bgr&255)<<16)
        Plot(x, y, rgb)
        
        pPixel+3
      Next x
      pLine + biPitch
    Next y

    StopDrawing()
    
  Else
  
    CloseFile(File)
    FreeImage(Image)
    ProcedureReturn 0
    
  EndIf
  
  ProcedureReturn Image
    
EndProcedure
Pour un exemple d'utilisation j'ai mis en ligne un exemple d'utilisation téléchargeable ici.
Le but n'est pas de faire une super fonction de chargement de bitmap (surtout pas avec des plot()...) mais d'utiliser la fonction Readfile() avec des structures qui soient pas bidons...
Ca marche mais si la taille de l'image dépasse 96*96 j'ai une erreur...
Et comme j'aime pas avoir une erreur même si elle n'est pas directement liée à FileRead (enfin j'espere =), si y'en a qui ont le temps de jeter un coup d'oeil... Bon le code est pas commenté... j'essairai de le commenter plus tard...

Dri
Dernière modification par Dr. Dri le lun. 04/juil./2005 8:37, modifié 1 fois.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: fread et fwrite inspirés du C

Message par Anonyme2 »

Dr. Dri a écrit : Ce code s'adresse surtout aux structures et je demande à ceux qui s'y connaissent pour me dire comment savoir si un fichier est ouvert, car je suis passé par usefile mais i le fichier n'est pas ouvert le compilateur génere une erreur (en mode test avec F5 en tout cas).
Récupère la valeur du Openfile et teste-là. SI = 0 le fichier est fermé sinon il est ouvert.

A remettre à 0 immédiatement après avoir utilisé le closefile()
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

La procédure est incomplète si on ne peut pas écrire plusieurs fois la même structure avec des valeurs différentes.

:)

J'ai rien dit, oups!
Dernière modification par nico le mer. 16/juin/2004 19:20, modifié 1 fois.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

@Denis
J'ai pas compris :silly:
@nico
J'ai pas compris :silly:

Dri
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Je ne suis pas sûr de l'utilité de la procédure:

Code : Tout sélectionner

Structure bidon 
  long.l 
  word.w 
  byte.b 
EndStructure 

tabsize = 5 

Dim tab1.bidon(tabsize-1) 
Dim tab2.bidon(tabsize-1) 

For i=0 To tabsize-1 
  tab1(i)\long = 4 * i 
  tab1(i)\word = 2 * i 
  tab1(i)\byte = 1 * i 
Next i 

Debug SizeOf(bidon)*5

If OpenFile(0, "bidon.dat")
  WriteData(@tab1(), SizeOf(bidon)*tabsize) 
  CloseFile(0) 
EndIf 

Debug "----------------"

If ReadFile(0, "bidon.dat")
  ReadData(@tab2(), SizeOf(bidon)*tabsize) 
  CloseFile(0) 
EndIf 

For i=0 To tabsize-1 
  Debug tab2(i)\long 
  Debug tab2(i)\word 
  Debug tab2(i)\byte 
  Debug " " 
Next i
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Par exemple

Code : Tout sélectionner

If OpenFile(0, "bidon.dat") 
  fwrite(@tab(0), SizeOf(bidon), tabsize, 0) 
  CloseFile(0) 
EndIf 
devient

Code : Tout sélectionner

Global FileOpen 
FileOpen = OpenFile(0, "bidon.dat")

If FileOpen 
   fwrite(@tab(0), SizeOf(bidon), tabsize, 0) 
  CloseFile(0) 
  FileOpen = 0
EndIf 
et tu teste dans fwrite et fread la variable FileOpen

FileOpen = 0 ==> le fichier n'est pas ouvert sinon c'est OK
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

@nico
Regarde mon deuxieme post... L'exemple se veut moins bidon!
Enfin c'est surtout qu'il y a une gestion des erreurs... Notament au niveau de la lecture si jamais on dépasse la taille du fichier...
@Denis
C'était surtout pour que les fonctions le fasse indépendament... Quand je fais un usefile() sur un numéro de fichier qui n'existe pas PB me le dit... Mais comment moi je fais pour le savoir ?
Par exemple en darkbasic on a fichier_est_ouvert = fileopen(numero)

Dri
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

essaye IsFile(#fichier)

Cette fonction existemais j'ai rien dans la doc, alors je ne sais pas son résultat :oops:
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

c'est pas dans la doc parce que c'est avec la 3.91beta :)
c'est comme tous les IsMachinTrucChose ,ça teste si le bidule existe :)
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Donc ca a été ajouté ^^

Et pour l'histoire des bitmaps qui dépassent pas 96*96 ?
Vous avez une idée ? Parce que là je comprend pas...

Dri
Répondre