Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

unpack et nombres réel issus de VMS.

16 réponses
Avatar
Thierry Thomas
Bonsoir,

Je dois récupérer un lot de données techniques qui avaient été créées
par des programmes Pascal sur un Vax (VMS), avec des formats INTEGER ou
REAL.

J'avais pensé à faire un script Perl pour les lire, à cause d'unpack, et
effectivement je récupère très bien les entiers, en mettant 'V' dans le
template. Par contre, je n'ai rien trouvé pour les réels, et il semble
que ça ne soit pas prévu dans l'unpack standard.

Y aurait-il un module complémentaire qui permette de lire ces réels ?

Merci.
--
Th. Thomas.

10 réponses

1 2
Avatar
Yves POINTIN
Thierry Thomas wrote:
Bonsoir,

Je dois récupérer un lot de données techniques qui avaient été créées
par des programmes Pascal sur un Vax (VMS), avec des formats INTEGER ou
REAL.

J'avais pensé à faire un script Perl pour les lire, à cause d'unpack, et
effectivement je récupère très bien les entiers, en mettant 'V' dans le
template. Par contre, je n'ai rien trouvé pour les réels, et il semble
que ça ne soit pas prévu dans l'unpack standard.

Y aurait-il un module complémentaire qui permette de lire ces réels ?

Merci.


Bonjour,

Voici une partie du code que j'ai utilisé sous Linux pour récupérer des
fichiers binaires écrits en FORTRAN (avec octets de contrôle) sous VAX

my @tbuf=`od -a $fich ` ;
my @pbuf=map(/[!^d{7}s+].+/g,@tbuf) ;
my $ligne="";
for my $ii (0..$#pbuf) {
$ligne=$ligne." ".$pbuf[$ii];
}
@tbuf=split(/s+/m,$ligne);
# print " t => @tbuf[0..40] n";
my @fbuf=`od -x $fich ` ;
$ligne="";
for my $ii (0..$#fbuf) {
$fbuf[$ii]=~ s/^d{7}s+// ;
$fbuf[$ii]=~ s/^*// ;
$ligne=$ligne." ".$fbuf[$ii];
}
# séparation et inversion des octets
$ligne=~ s/(w{2})(w{2})/$2 $1/g ;
@pbuf=split(/s+/m,$ligne);
# print " p => @pbuf[0..$#pbuf] n";
@fbuf=() ;
for (my $ii=1;$ii<= $#pbuf-3 ; $ii+=4) {
$fbuf[$ii/4]=unpack("f",pack("H8", substr("0" x 8
.$pbuf[$ii+2].$pbuf[$ii+3
].$pbuf[$ii].$pbuf[$ii+1], -8)))/4;
}

# print " f => @fbuf[0..$#pbuf/4] n";

Il fallait ensuite se resynchroniser sur les octets de contrôle au début
des enregistrements réels (code 66 , 3 , nombre de valeurs, en entier,
je crois)

Si ça peut servir.

Cordialement,

--
Dr. POINTIN Yves B.
perl -e "$_='';1 while
s/(.{3})(.{3})?/$_{$2}=$1,$2/e; ; print while $_=$_{$_};"

Avatar
Paul Gaborit
À (at) Sat, 17 Mar 2007 21:13:23 +0000 (UTC),
Thierry Thomas écrivait (wrote):
Je dois récupérer un lot de données techniques qui avaient été créées
par des programmes Pascal sur un Vax (VMS), avec des formats INTEGER ou
REAL.

J'avais pensé à faire un script Perl pour les lire, à cause d'unpac k, et
effectivement je récupère très bien les entiers, en mettant 'V' dan s le
template. Par contre, je n'ai rien trouvé pour les réels, et il semble
que ça ne soit pas prévu dans l'unpack standard.

Y aurait-il un module complémentaire qui permette de lire ces réels  ?


En module tout prêt, je ne sais pas. Mais avec les fonctions de base
de Perl, c'est faisable. Par contre, il vous faut en savoir un peu
plus sur sur le format de stockage des doubles (nombre d'octets
utilisés, little ou big endian, taille en bits de la mantisse et de
l'exposant,etc.) tant sur le VMS d'origine que sur la plateforme où
tourne votre script. Si en plus, vous avez quelques petits fichiers de
données dont le contenu est connu, c'est encore mieux pour faire les
tests ou même pour redécvourir tout cela. Après, ce n'est plus que de
la cuisine interne pour réordonner les octets voire les bits d'un
format natif à l'autre...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Paul Gaborit
À (at) Mon, 19 Mar 2007 10:31:05 +0100,
Yves POINTIN écrivait (wrote):
[...]
Voici une partie du code que j'ai utilisé sous Linux pour récupérer
des fichiers binaires écrits en FORTRAN (avec octets de contrôle) sous
VAX


Joli (!?!)... Tous les appels à 'od' aurait pu être gérer directement
en Perl. De plus, les enregistrements des fichiers binaires FORTRAN
sont un peu particulier (il y a effectivement un marqueur au début et
un à la fin). Ceci étant, il reste la partie sur l'ordonancement des
octets des valeurs flottantes qui est intéressantes (puisque
manifestement il n'y a que ça à faire). Mais là, l'ordre dépend de la
plateforme d'arrivée... qu'on ne connait pas encore.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Thierry Thomas
Lundi 19 mars 2007 à 10:25 GMT, Paul Gaborit a écrit :

Joli (!?!)... Tous les appels à 'od' aurait pu être gérer directement
en Perl. De plus, les enregistrements des fichiers binaires FORTRAN
sont un peu particulier (il y a effectivement un marqueur au début et
un à la fin). Ceci étant, il reste la partie sur l'ordonancement des
octets des valeurs flottantes qui est intéressantes (puisque
manifestement il n'y a que ça à faire). Mais là, l'ordre dépend de la
plateforme d'arrivée... qu'on ne connait pas encore.


Je ne connais pas encore la plate-forme finale avec certitude, mais ça
sera sans doute un i386 sous Linux.

Quoiqu'il en soit, je peux faire cette moulinette intermédiaire sur
n'importe quelle machine à ma disposition, le but serait de convertir
mes fichiers en CSV / ASCII avec des print.
--
Th. Thomas.

Avatar
Thierry Thomas
Lundi 19 mars 2007 à 10:11 GMT, Paul Gaborit a écrit :

En module tout prêt, je ne sais pas. Mais avec les fonctions de base
de Perl, c'est faisable. Par contre, il vous faut en savoir un peu
plus sur sur le format de stockage des doubles (nombre d'octets
utilisés, little ou big endian, taille en bits de la mantisse et de
l'exposant,etc.) tant sur le VMS d'origine que sur la plateforme où
tourne votre script. Si en plus, vous avez quelques petits fichiers de
données dont le contenu est connu, c'est encore mieux pour faire les
tests ou même pour redécvourir tout cela. Après, ce n'est plus que de
la cuisine interne pour réordonner les octets voire les bits d'un
format natif à l'autre...


Comme unpack traitait les entiers, j'avais imaginé qu'il y aurait
quelque chose pour les réels... Mais s'il n'y a pas, je vais devoir
vaincre ma flemme et m'y coller ! Merci pour vos réponses.
--
Th. Thomas.

Avatar
Paul Gaborit
À (at) Mon, 19 Mar 2007 18:09:15 +0000 (UTC),
Thierry Thomas écrivait (wrote):
Comme unpack traitait les entiers, j'avais imaginé qu'il y aurait
quelque chose pour les réels... Mais s'il n'y a pas, je vais devoir
vaincre ma flemme et m'y coller ! Merci pour vos réponses.


Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
sysread() en lisant si possible, par petits morceaux de taille connue.

Pour faire une première décomposition de ce qui est lu, unpack() en
lisant directement les entiers (via le bon type selon la plateforme
d'origine) et en lisant un simple groupe d'octets pour chaque flottant
(il faut quand même connaître sa taille).

Pour réordonner les octets ou même les bits au sein d'un flottant (vu
comme un groupes d'octets ou de bits), on peut utiliser vec().

Avec de la chance, un simple réordonnancement des octets suffit et on
peut ensuite utiliser les types flottants natifs de unpack ('f' ou
'd') pour relire les flottants.

Mais dans le cas où le nombre de bits de la mantisse ou de l'exposant
serait différent entre les plateformes, il faudra faire des choix
limitatifs (et tout faire via vec() pour extraire mantisse et exposant
séparément).

Mais, c'est faisable et très agréable à coder avec Perl.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Paul Gaborit
À (at) Tue, 20 Mar 2007 01:29:07 +0100,
Paul Gaborit écrivait (wrote):
Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
~~~~~~~~~~~

sysread() en lisant si possible, par petits morceaux de taille connue.


Un simple open() suivit de binmode() suffit amplement pour ouvrir le
fichier en mode binaire sur toute les plateformes. Et toc ! ;-)

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Nicolas George
Paul Gaborit wrote in message :
Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
sysread() en lisant si possible, par petits morceaux de taille connue.


Quelle drôle d'idée. sysopen est utile quand on veut contrôler finement les
options d'ouverture, sysread pour travailler avec des fichiers spéciaux sans
tampon. Mais ici, ça me semble absolument inutile et plutôt une mauvaise
idée.

Avatar
Paul Gaborit
À (at) 20 Mar 2007 11:19:45 GMT,
Nicolas George <nicolas$ écrivait (wrote):
Paul Gaborit wrote in message :
Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
sysread() en lisant si possible, par petits morceaux de taille connue.


Quelle drôle d'idée. sysopen est utile quand on veut contrôler finement les
options d'ouverture, sysread pour travailler avec des fichiers spéciaux sans
tampon. Mais ici, ça me semble absolument inutile et plutôt une mauvaise
idée.


Oui, oui. Je voulais insister sur sysread() qui, dans ce cas, est
absolument nécessaire et emporté par mon élan, j'ai tapé sysopen() au
lieu de open() (suivi de binmode())...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>


Avatar
Nicolas George
Paul Gaborit wrote in message :
Oui, oui. Je voulais insister sur sysread() qui, dans ce cas, est
absolument nécessaire


Pourquoi donc ?

1 2