Fichier IFS - UTF-16
Fichier IFS - UTF-16
Bonjour,
je rencontre une problématique d'encodage au niveau d'un fichier CSV que je crée et alimente dans l'IFS.
Le client exige que les données soient en UTF-16. J'ai utilisé plusieurs méthodes pour convertir les données (API iconv, fonction %ucs2, fonction disponible sur le dépôt github FrenchIBMi etc.) mais à chaque fois le client me dit que cela n'est pas bon. J'arrive correctement à visualiser le contenu par une session 5250 mais c'est illisible une fois téléchargé sur un environnement Windows.
En utilisant Notepad++ pour obtenir les informations d'encodage, j'obtiens ceci comme informations :
-pour un fichier type que le client a envoyé : Windows (CR LF) et UCS-2 LE BOM. Le fichier se lit correctement.
-pour un fichier que je génère et que je tente de transformer avec les méthodes cité plus haut : Macintosh (CR) et ANSI. Le fichier est illisible, avec plusieurs caractères NUL, EOT, SYN etc.
Auriez-vous une idée du problème ?
Merci d'avance.
je rencontre une problématique d'encodage au niveau d'un fichier CSV que je crée et alimente dans l'IFS.
Le client exige que les données soient en UTF-16. J'ai utilisé plusieurs méthodes pour convertir les données (API iconv, fonction %ucs2, fonction disponible sur le dépôt github FrenchIBMi etc.) mais à chaque fois le client me dit que cela n'est pas bon. J'arrive correctement à visualiser le contenu par une session 5250 mais c'est illisible une fois téléchargé sur un environnement Windows.
En utilisant Notepad++ pour obtenir les informations d'encodage, j'obtiens ceci comme informations :
-pour un fichier type que le client a envoyé : Windows (CR LF) et UCS-2 LE BOM. Le fichier se lit correctement.
-pour un fichier que je génère et que je tente de transformer avec les méthodes cité plus haut : Macintosh (CR) et ANSI. Le fichier est illisible, avec plusieurs caractères NUL, EOT, SYN etc.
Auriez-vous une idée du problème ?
Merci d'avance.
Re: Fichier IFS - UTF-16
Bonjour,
comment transférez-vous le fichier produit vers le client, selon la méthode il peur y avoir conversion de caractère pendant le transfert, par exemple si vous déposer le fichier par FTP chez votre client pour être certain qu'il voit le fichier tel que vous l'avez produit il faut faire un transfert binaire.
comment transférez-vous le fichier produit vers le client, selon la méthode il peur y avoir conversion de caractère pendant le transfert, par exemple si vous déposer le fichier par FTP chez votre client pour être certain qu'il voit le fichier tel que vous l'avez produit il faut faire un transfert binaire.
Nicolas
(sujet inconnu)
Bonjour,
je transmet le fichier au client par mail via la commande SNDSMTPEMM. Je rencontre le même problème sur mon poste lorsque je récupère le fichier par ACS ou FTP en mode binaire.
En complément d'information, voici le code source généré, qui utilise les API "standard" de manipulation de fichier
je transmet le fichier au client par mail via la commande SNDSMTPEMM. Je rencontre le même problème sur mon poste lorsque je récupère le fichier par ACS ou FTP en mode binaire.
En complément d'information, voici le code source généré, qui utilise les API "standard" de manipulation de fichier
Code : Tout sélectionner
dcl-s chaine varchar(999999) inz;
dcl-s chaineUCS2 ucs2(999999) inz ccsid(1200);
fd=open(nomFichier:O_CREAT+O_WRONLY+O_CCSID:0:1252);
chaineUCS2=%ucs2(%trim(chaine));
callp write(fd: %addr(chaineUCS2):%len(%trimr(chaineUCS2))*2);
callp close(fd);
(sujet inconnu)
Je pense qu'il faudrait utiliser
open(nomFichier:O_CREAT+O_WRONLY+O_CCSID:0:1200);
pour que le fichier soit créé avec le CCSID 1200 même s'il n'y a pas de conversion (il faut supprimer le fichier pour être sûr s'il existe déjà)
et ajouter un write(fd:x'FFFE':2); avant l'écriture des données qui est le BOM UTF-16BE qui va indiquer à Windows que les données qui suivent sont en UTF-16 big endian (cad le CCSID 1200)
est-ce que ça fonctionne comme ça ?
open(nomFichier:O_CREAT+O_WRONLY+O_CCSID:0:1200);
pour que le fichier soit créé avec le CCSID 1200 même s'il n'y a pas de conversion (il faut supprimer le fichier pour être sûr s'il existe déjà)
et ajouter un write(fd:x'FFFE':2); avant l'écriture des données qui est le BOM UTF-16BE qui va indiquer à Windows que les données qui suivent sont en UTF-16 big endian (cad le CCSID 1200)
est-ce que ça fonctionne comme ça ?
Nicolas
(sujet inconnu)
Il y a du progrès !!
C'est une méthode que j'avais auparavant utilisé mais abandonné pour la raison suivante : au niveau des informations renvoyés par Notepad++, je suis bien en Windows (CR LF) et UCS-2 LE BOM. En revanche, si je le consulte dans un environnement Windows (récupéré par transfert FTP en mode binaire), le document est composé de caractères type chinois...
Il ne doit pas manquer grand chose mais quoi ?
C'est une méthode que j'avais auparavant utilisé mais abandonné pour la raison suivante : au niveau des informations renvoyés par Notepad++, je suis bien en Windows (CR LF) et UCS-2 LE BOM. En revanche, si je le consulte dans un environnement Windows (récupéré par transfert FTP en mode binaire), le document est composé de caractères type chinois...
Il ne doit pas manquer grand chose mais quoi ?
(sujet inconnu)
En modifiant le BOM, le fichier est correctement lisible par Windows. La seule différence c'est que le fichier semble être en UCS-2 BE BOM (et non LE BOM).
Si je remets le BOM FFFE, le fichier devient de nouveau illisible.
J'espère que le client ne sera pas trop exigeant de ce côté là...
Je vous tiens au courant.
Si je remets le BOM FFFE, le fichier devient de nouveau illisible.
J'espère que le client ne sera pas trop exigeant de ce côté là...
Je vous tiens au courant.
Re: (sujet inconnu)
S'il est exigeant il faudra mettre le BOM UTF16-LE et inverser les octets de deux par deux dans chaineUCS2, je pense que ça devrait suffire
Nicolas
(sujet inconnu)
vazymimil YOU ARE MY STAR !!!!
Le client a validé le nouveau format de fichier. Il ne manquait pas grand chose finalement.
Merci beaucoup pour votre aide.
Par contre votre dernière remarque a éveillé ma curiosité :
Le client a validé le nouveau format de fichier. Il ne manquait pas grand chose finalement.
Merci beaucoup pour votre aide.
Par contre votre dernière remarque a éveillé ma curiosité :
Comment procéder de la sorte ?il faudra mettre le BOM UTF16-LE et inverser les octets de deux par deux dans chaineUCS2
Re: (sujet inconnu)
En fait il y a une api pour ça :QlgTransformUCSData
un exemple:
dcl-pr QlgTransformUCSData int(10) extproc(*dclcase);
xformtype int(10) value;
inbuf pointer;
inbytesleft uns(10);
outbuf pointer;
outbytesleft uns(10);
outspacereq uns(10);
end-pr;
dcl-s donneesUTF16LE char(%size(chaineucs2));
dcl-s ret like(QlgTransformUCSData);
dcl-s p_inbuf pointer;
dcl-s inbytesleft uns(10);
dcl-s p_outbuf pointer;
dcl-s outbytesleft uns(10);
dcl-s outspacereq uns(10);
p_inbuf = %addr(chaineUCS2);
inbytesleft = %len(chaineUCS2) * 2;
p_outbuf = %addr(donneesUTF16LE);
outbytesleft = %size(donneesUTF16LE);
ret = QlgTransformUCSData(040052:p_inbuf:inbytesleft:p_outbuf:outbytesleft:outspacereq);
if ret <> 0;
dsply %char(ret);
endif;
un exemple:
dcl-pr QlgTransformUCSData int(10) extproc(*dclcase);
xformtype int(10) value;
inbuf pointer;
inbytesleft uns(10);
outbuf pointer;
outbytesleft uns(10);
outspacereq uns(10);
end-pr;
dcl-s donneesUTF16LE char(%size(chaineucs2));
dcl-s ret like(QlgTransformUCSData);
dcl-s p_inbuf pointer;
dcl-s inbytesleft uns(10);
dcl-s p_outbuf pointer;
dcl-s outbytesleft uns(10);
dcl-s outspacereq uns(10);
p_inbuf = %addr(chaineUCS2);
inbytesleft = %len(chaineUCS2) * 2;
p_outbuf = %addr(donneesUTF16LE);
outbytesleft = %size(donneesUTF16LE);
ret = QlgTransformUCSData(040052:p_inbuf:inbytesleft:p_outbuf:outbytesleft:outspacereq);
if ret <> 0;
dsply %char(ret);
endif;
Nicolas