[Resolu] Créer un fichier à partir d'une variable (string)

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

[Resolu] Créer un fichier à partir d'une variable (string)

Message par falsam »

PB 5.31 (x86) - Windows 10

Bonjour.

■ Les grandes lignes de mon application.
- Je code une application qui mémorise dans une map le contenu de fichiers que je sélectionne.
- Un des éléments de la structure de cette map est un buffer alphanumérique qui mémorise le contenu d'un fichier.
- Quand on quitte mon application, cette map est mémorisée dans un fichier JSON pour traitement ultérieur.

- Le code est compilé sans l'option unicode.

■ Le souci que je rencontre.
Quand je sélectionne cette map, les fichiers sont reconstitués dans un dossier cache de mon application.
Le souci est que les fichiers du type images (PNG, JPG, .....) ne s'affichent pas bien qu'ayant la taille d'origine.

J'ai isolé la manière dont je procède dans ce petit code qui va vous permettre de choisir un ficher qui sera lu et automatiquement crée à nouveau afin de voir le résultat. Le fichier ainsi crée se nommera "dummy" suivit de l'extension du fichier d'origine. Merci d'avance pour votre aide.

Code : Tout sélectionner

EnableExplicit

Global File.s, FileExt.s, Buffer.s, length, bytes, *MemoryID

;Choix du fichier à lire
file = OpenFileRequester("Choisissez un fichier", "", "", 0)

;Mémorisation de l'extension du fichier
FileExt = GetExtensionPart(file)

If file <> ""
  If ReadFile(0, file)
    
    ;Init zone mémoire
    length = Lof(0)
    *MemoryID = AllocateMemory(length)
    
    ;Lecture du fichier
    If *MemoryID
      bytes = ReadData(0, *MemoryID, length)
      Debug "Nombre de bytes lus: " + Str(bytes)
      
      Buffer = PeekS(*MemoryID, bytes)
      
    EndIf
    CloseFile(0)
    
    ;Test : Creation du fichier pour voir si résultat identique
    *MemoryID = AllocateMemory(bytes)
    PokeS(*MemoryID, Buffer, bytes)
    
    CreateFile(0, "dummy." + FileExt)
    WriteData(0, *MemoryID, bytes)
    CloseFile(0)
  EndIf
EndIf
Sélectionner une image puis essayer d'afficher le résultat crée avec votre visualiseur d'images favori.
Dernière modification par falsam le sam. 19/sept./2015 16:08, modifié 1 fois.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Créer un fichier à partir d'une variable (string)

Message par falsam »

Tu me laisse pas le temps de répondre à ton premier commentaire, alors je vais répondre sur le second. :wink:

Quand je Peek mon image, j'arrive à visualiser cette image avec un CatchImage(0, *MemoryID).

Je laisse le code du premier message et je poste un nouveau qui permet de voir l'image aprés le Peek

Code : Tout sélectionner

EnableExplicit
UsePNGImageDecoder()
UsePNGImageEncoder()

UseJPEGImageDecoder()
UseJPEGImageEncoder()

Global File.s, FileExt.s, Buffer.s, length, bytes, *MemoryID

;Choix du fichier à lire
file = OpenFileRequester("Choisissez un fichier", "", "", 0)

;Mémorisation de l'extension du fichier
FileExt = GetExtensionPart(file)

If file <> ""
  If ReadFile(0, file)
    
    ;Init zone mémoire
    length = Lof(0)
    *MemoryID = AllocateMemory(length)
        
    ;Lecture du fichier
    If *MemoryID
      bytes = ReadData(0, *MemoryID, length)
      Debug "Nombre de bytes lus: " + Str(bytes)
      
      Buffer = PeekS(*MemoryID, bytes)
    EndIf
    CloseFile(0)
    
    ;Création de l'image d'origine à visualiser dans le débugger
    CatchImage(0, *MemoryID)  
    
    ;Test : Creation du fichier pour voir si résultat identique
    *MemoryID = AllocateMemory(bytes)
    If *MemoryID
      PokeS(*MemoryID, Buffer, bytes)
      
      ;A partir de là, ça va se gater
      ;CatchImage n'est là que pour voir si j'ai bien une image
      ;Comme vous allez le voir, ce n'est pas le cas.
      Debug CatchImage(1, *MemoryID)  ;Aie error !
      
      CreateFile(0, "dummy." + FileExt)
      WriteData(0, *MemoryID, bytes)
      CloseFile(0)
    EndIf
    
  EndIf
EndIf

;Ici on peut voir l'image 0
ShowLibraryViewer("image", 0)
CallDebugger

Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Créer un fichier à partir d'une variable (string)

Message par nico »

Comme le souligne Spock, tu ne peux pas transformer directement du binaire en Chaine de caractères.

Des personnes ont déjà créé des codes afin d'inclure du binaire en data.s afin de l'inclure dans le code source, ce qu'il signifie qu'il faut encoder puis décoder.

Ben voilà le résultat, en utilisant la librairie Base64:

Code : Tout sélectionner

EnableExplicit

Global File.s, FileExt.s, Buffer.s, length, bytes, *MemoryID
Global Encoded$

;Choix du fichier à lire
file = OpenFileRequester("Choisissez un fichier", "", "", 0)

;Mémorisation de l'extension du fichier
FileExt = GetExtensionPart(file)

If file <> ""
  If ReadFile(0, file) <> 0
    
    ;Init zone mémoire
    length = Lof(0)
    If length > 0
      *MemoryID = AllocateMemory(length)
      
      ;Lecture du fichier
      If *MemoryID <> 0
        bytes = ReadData(0, *MemoryID, length)
        Debug "Nombre de bytes lus: " + Str(bytes)
        
        ; il faut ajouter au moins 33% supplémentaires
        Encoded$ = Space(length + (length/3)) 
        
        If Base64Encoder(*MemoryID, length, @Encoded$, length + (length/3)) > 0
          ; Transformé en chaine de caractères
          Debug Encoded$ 
          
        EndIf
      EndIf
    EndIf
    CloseFile(0)
  EndIf
EndIf


;Test : Creation du fichier pour voir si résultat identique
*MemoryID = AllocateMemory(length)
If *MemoryID > 0
  
  Debug Base64Decoder(@Encoded$, StringByteLength(Encoded$), *MemoryID, length)
  ; Décodé afin de retrouver le binaire
  Debug *MemoryID
  
  If CreateFile(0, "C:\Users\Nico\Desktop\dummy." + FileExt) <> 0
    WriteData(0, *MemoryID, bytes)
    CloseFile(0)
  EndIf
EndIf
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Créer un fichier à partir d'une variable (string)

Message par falsam »

Oops je suis un con ! J'ai totalement oublié d'utiliser Base64Encoder() alors que je l'ai déja utilisé dans quelques codes que je présente sur ce forum comme Canvas Variation ou MindMap dans lequel je stocke des images dans un fichier xml.
:arrow: http://www.purebasic.fr/french/viewtopi ... 40#p143440

Nico merci beaucoup pour ton aide :wink:

Sujet Résolu et ça servira surement pour d'autres utilisateurs.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [Resolu] Créer un fichier à partir d'une variable (strin

Message par falsam »

Spock a écrit :ha.. bon je vais me parfumer :roll:
Je suis tellement content de la solution de nico, que dans ma précipitation j'ai oublié de te remercier pour tes commentaires. (Si ça c'est pas spontané :mrgreen:)
Dernière modification par falsam le sam. 19/sept./2015 16:41, modifié 1 fois.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: [Resolu] Créer un fichier à partir d'une variable (strin

Message par nico »

Canvas Variation ou MindMap
Super bien foutu MindMap. :D
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [Resolu] Créer un fichier à partir d'une variable (strin

Message par falsam »

nico a écrit :Super bien foutu MindMap.
Merci Nico mais maintenant que je connais mieux PureBasic, j'ai vu quelques erreurs de conception dans ce code. Les schémas récursifs sont impossible à faire par exemple.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [Resolu] Créer un fichier à partir d'une variable (strin

Message par falsam »

Spock a écrit :va etre content Nico
Comme tu le vois, je suis net en ce moment. Je corrige mon commentaire.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
celtic88
Messages : 309
Inscription : sam. 12/sept./2015 14:31
Localisation : Alger

Re: [Resolu] Créer un fichier à partir d'une variable (strin

Message par celtic88 »

slt falsam ta méthode marche seulement c i tu active le mode "#PB_UTF8" dans "PokeS" et "PeekS " et je te conseil pas de l faire car c est deux fonction son fais pour lire des fichiers Texte pas binaire !comme ci tu ouvre ton image avec notepad est sa ce fait pas non :( :P
.....i Love Pb :)
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [Resolu] Créer un fichier à partir d'une variable (strin

Message par falsam »

Oui Celtic tu as raison. Je me suis trompé et j'ai appliqué la méthode de Nico. Merci pour ton commentaire :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: [Resolu] Créer un fichier à partir d'une variable (strin

Message par nico »

marche seulement c i tu active le mode "#PB_UTF8" dans "PokeS" et "PeekS "
Non Celtic, a cause des 0 qui signifient la fin d'une chaîne de caractère, le fait que cela puisse fonctionner serait un pur concours de circonstance.
Répondre