Ecrire un fichier binaire à partir d'une ressource [Résolu]

Signaler
Messages postés
175
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
3 avril 2020
-
Messages postés
175
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
3 avril 2020
-
Bonjour,

Je me heurte actuellement à un problème qui commence à m'agacer fortement.

J'ai inséré dans le fichier de ressources Resources.resx de mon projet un fichier binaire (une base de données Access vide, mais ce pourrait être autre chose).

Quand j'essaie de créer un fichier sur le disque à partir de cette ressource, je n’obtiens jamais la même chose que l'original. Il s'agit vraisemblablement d'un problème d'encoding, mais je n'arrive pas à le résoudre.

Voici le code que j'utilise :
byte[] EmptyBase = (byte[]) Properties.Resources.ResourceManager.GetObject("EmptyBase");
StreamWriter SW = new StreamWriter(dlg.FileName, false, Encoding.Default);
foreach(byte Octet in EmptyBase)
    SW.Write(Convert.ToChar(Octet));
SW.Close();


- J'ai essayé TOUTES le valeurs de Encoding (Unicode, ASCII, default, etc) sans résultat.
- j'ai essayé de ne pas employer Convert mais de faire un cast, sans résultat
- J'ai essayé sans cast ni convert, les octets sont écrits sous forme numérique (abc = "656667", etc.)
J'ai aussi essayé d'écrire tout le fichier en une seule fois au lieu d'octet par octet, mêmes résultats.

Il y a surement une façon simple de faire ça, mais je cale lamentablement...
Help !

Le code original (fichier sur le disque) :


Le code généré par l'appli avec Encoding.Default :


Le code généré par l'appli avec Encoding.ASCII :


Le code généré par l'appli avec Encoding.Unicode:

1 réponse

Messages postés
175
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
3 avril 2020

J'ai trouvé !
(C'est bien, je fais les questions et les réponses - J'ai encore posté trop vite...)

En écumant une fois de plus le web, j'ai fini par trouver la solution chez Microsoft.
Au lieu d'un StreamWriter, il suffisait d'utiliser un FileWriter.

Ça donne :
byte[] EmptyBase = (byte[])Properties.Resources.ResourceManager.GetObject("EmptyBase");
FileStream FS = new FileStream(dlg.FileName, FileMode.Create);
foreach (byte Octet in EmptyBase)
    FS.WriteByte(Octet);
FS.Close();


Et c'est tout bon, la sortie est conforme à l'original
Et il n'est plus question d'encoding, ce qui est normal puisqu'on joue avec des octets bruts.
CQFD.

Il me reste à optimiser la chose en cherchant comment écrire en une seule fois le tableau d'octets. Mais cela ne devrait pas être un problème, et si je ne trouve pas je pourrai m'en passer, le fichier faisant moins de 200 Ko.
Messages postés
175
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
3 avril 2020

Encore trouvé :
FS.Write(EmptyBase, 0, EmptyBase.Length);
Messages postés
14676
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
3 juin 2020
143
Et il n'y a pas System.IO.File.WriteAllBytes ?
Messages postés
175
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
3 avril 2020

FileStream.Write écrit soit un octet si on lui donne 1 octet, soit tout le tableau si on lui donne le tableau.d'octet.
EmptyBase est un byte[ ], et donc FS.Write(EmptyBase, 0, EmptyBase.Length) écrit tout le tableau d'un coup (en fait, depuis l'offset donné et selon la longueur fournie). Pas besoin de WriteAll, Write est polymorphe.
PS : Il faut bien sur supprimer la boucle et ne laisser que le Write.
Messages postés
14676
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
3 juin 2020
143
Quand tu as un tableau d'octet en source, l'avantage de WriteAllBytes est que ça fait tout en un seul bloc (ouverture, écriture et fermeture) donc pas de risque de laisser le fichier ouvert par erreur.
Messages postés
175
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
3 avril 2020

C'est effectivement plus simple et efficace. J'ai pris note et modifié mon code.
Merci.