Fil d’Ariane du forum – Vous êtes ici :ForumForums techniques: AS/400Lecture des enregistrements d'un …
Vous devez vous identifier pour créer des messages et des sujets.

Lecture des enregistrements d'un fichier dans l'IFS via RPGLE

Bonjour,

Au risque de poser une question simple, je voudrais savoir comment lire les données d'un fichier dans l'IFS directement à partir d'un programme en RPGLE.

Cela m'éviterait un transfert par CPYFRMIMPF de / vers QSYS.LIB

Merci
FRED

Bonjour,

parmi les Integrated File System APIs tu dois utiliser open() et read()

le mieux est d'aller voir l'ebook de Scott Klement sur le sujet

Bonjour,

J'ai fait un petit programme de lecture de fichier dans l'IFS, mais je le trouve assez compliqué dans la mesure ou il me lit tout ce qu'il trouve et pas uniquement les caractères jusqu'à un LFCR.

voici le petit programme en question

H DATEDIT(*YMD) dftactgrp(*no) ACTGRP('QILE') bnddir('BNDDIR')
// ouverture du fichier
D open PR 10I 0 extproc('open')
D path * value options(*string)
D oflag 10I 0 value
D mode 10U 0 value options(*nopass)
D codepage 10U 0 value options(*nopass)
//
D O_RDONLY S 10I 0 INZ(1)
D O_TEXTDATA S 10I 0 INZ(16777216)
// Lecture du fichier
D read PR 10I 0 extproc('read')
D fildes 10I 0 value
D buf * value
D nbyte 10U 0 value
// Fermeture du fichier
D close PR 10I 0 extproc('close')
D fildes 10I 0 value
//

D fd S 10I 0
D data S 500A
D dataF S 22A
D BytesRead S 10I 0
D dataread S 9899A
D msg S 52A
D posit S 3 0

/FREE
fd = open('/RECEPTION/LS.TXT':
O_RDONLY + O_TEXTDATA);

// Lecture d'un enregistrement
Bytesread = read(fd:%addr(dataread):%size(dataread));
Data = %Subst(DataRead:1:bytesread);

// Fermeture du fichier
callp close(fd);
*inlr = *on;
/END-FREE

Effectivement à toi de gérer l'end of line avec des %scan, sauf si tu connais la longueur exacte d'un enregistrement dans ton fichier.
Par contre attention, utilises plutôt des varchar que des char.

bonjour,

Dans quel cas, il, faudrait que j'utilise des varchar ?

Je vais effectivement ajouter un %scan pour chercher X'25' et ainsi faire la "séparation" des enregistrements.

FRED

Fred,
Es-tu arrivée à tes fins ? As-tu réussi a scanner correctement le fichier IFS ?
Si ce fichier est en ASCII, la fin d'un record devrait être x'0d0a', si EBCDIC x'0d25'.

Comme ça :
H DFTACTGRP(*NO) BNDDIR('QC2LE')

* -- PROTOTYPES DES FONCTIONS D'I/O
* open()
D fopen PR * ExtProc('_C_IFS_fopen')
D fildes * value options(*string)
D mode * value options(*string)
* fgets()
D fgets PR * ExtProc('_C_IFS_fgets')
D buf * value
D size 10I 0 value
D fildes * value
* close()
D close PR 10I 0 ExtProc('_C_IFS_fclose')
D fildes * value
* __errno
D get_errno PR * ExtProc('__errno')
D ptrToErrno S *
D errno S 10I 0 based(ptrToErrno)

* -- variables
D fd S *
D nomfic S 32A
D idmsg S 7A
D ret S 10I 0
D data S 1000A
D ligne S 1000A VARYING

/free

// initialisation
nomfic = '/tmp/fichtest.txt';

// ouverture du fichier
fd = fopen(%trim(nomfic): 'r');
if fd = *null;
// erreur ouverture
ptrToErrno = get_errno();
idmsg = 'CPE' + %char(errno);
dsply idmsg;
*inlr = *on;
return;
endif;

// lecture du fichier
dow (fgets(%addr(data): %size(data): fd) *null);
ligne = %str(%addr(data));
enddo;

// fermeture du fichier
ret = close(fd);

// fin
*inlr = *on;
return;

/end-free
on n'a pas besoin de gérer l'EOL (grâce à fgets). La seule chose chose que je ne suis pas arrivé à faire, c'est déterminer la longueur des données retournées dans la variable ligne.

P.S. Toujours pas possible de mettre des pièces attachées dans les discussions ?

Citation de remit

La seule chose chose que je ne suis pas arrivé à faire, c'est déterminer la longueur des données retournées dans la variable ligne.

Ajoute alors
dsply %len(ligne);
dans ton programme.

NB : le caractère de fin de ligne est compris dans la longueur.

Bonjour,

J'ai effectivement ajouté un %scan pour trouver le fin de mon 1er enregistrement,
et comme je n'ai besoin que du 1er enregistrement, tout baigne.

Pour lire plusieurs enregistrements, il faut gérer un buffer des données en cours :

- Découper les zones avec %scan du caractère X'25'
- Faire un %subst pour limiter les caractères d'une ligne et ainsi extraire les caractères d'un enregistrement
- Ajouter la prochaine lecture par concaténation si on ne trouve plus de X'25'

L'idéal serait d'avoir un moyen "simple" de lire dans l'IFS les enregistrements 1 par 1 sans connaitre la taille au préalable.

Est-ce la cas avec la fonction "_C_IFS_FGETS" ???

FRED

Bonjour,
En effet la fonction _C_IFS_FGETS permet de lire ligne par ligne.