MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 2022
-
Modifié le 22 sept. 2019 à 14:16
MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 2022
-
23 sept. 2019 à 11:15
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 :
MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 20222 22 sept. 2019 à 15:49
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.
MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 20222 22 sept. 2019 à 16:03
Encore trouvé :
FS.Write(EmptyBase, 0, EmptyBase.Length);
NHenry
Messages postés15069Date d'inscriptionvendredi 14 mars 2003StatutModérateurDernière intervention29 mai 2023158 22 sept. 2019 à 16:34
Et il n'y a pas System.IO.File.WriteAllBytes ?
MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 20222 Modifié le 22 sept. 2019 à 17:27
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.
NHenry
Messages postés15069Date d'inscriptionvendredi 14 mars 2003StatutModérateurDernière intervention29 mai 2023158 22 sept. 2019 à 22:26
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.
MGD Software
Messages postés193Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention23 avril 20222 23 sept. 2019 à 11:15
C'est effectivement plus simple et efficace. J'ai pris note et modifié mon code.
Merci.
22 sept. 2019 à 16:03
22 sept. 2019 à 16:34
Modifié le 22 sept. 2019 à 17:27
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.
22 sept. 2019 à 22:26
23 sept. 2019 à 11:15
Merci.