Last Updated on 2 Settembre 2020 by Roberto De Pedrini
Questo post contiene delle informazioni che vanno ad arricchire ulteriormente il post di Massimo Balgera su Gestione files in IFS :
https://blog.faq400.com/it/programmazione/varie-programmazione-ibm-i/gestione-files-in-ifs/
con l’esempio di una soluzione adottata su una versione 7.1 di IBM introducendo anche il concetto di UDTF (User Defined Table Function):
Index
Scenario da risolvere
Nel caso che riporto partendo da un sistema IBM i 7.1 avevo la necessità di :
- Scrivere un file su una cartella condivisa di un server che è raggiungibile nella rete locale
- Attendere qualche secondo di elaborazione (sul server di destinazione gira un applicativo che elabora il file in ingresso e genera un file di uscita in una cartella definita)
- Leggere i file generati dall’applicativo nella cartella di output ed eventualmente fare delle azioni sui file
Per soddisfare il primo punto ho configurato il file system QNTC di IBM i in modo da poter raggiungere le cartelle condivise del server e scriverle tramite FTP.
Per ulteriori informazioni su QNTC potete leggere : QNTC – Accedere a informazioni su server remoti
https://blog.faq400.com/it/system-administration/qntc-accedere-a-informazioni-su-server-remoti/
Lettura indirizzario da IFS o QNTC
Per la lettura dei file su IFS non potevo adottare la scelta suggerita da Massimo Balgera nel suo post perchè il sistema sul quale ho lavorato non era così aggiornato. Inoltre, avevo anche la necessità di leggere il contenuto del file per capire se fare delle azioni aggiuntive sul file (copia, cancellazione, trasferimento …)
Per la lettura di un indirizzario di IFS sulla versione V7R1, ho applicato la soluzione suggerita in questo articolo di Scott Klement : https://www.scottklement.com/udtf/ifsDirArticle.html
La soluzione prevede la creazione di una UDTF (User Defined Table Function). Nel link sopra indicato sono riportati degli esempio, è possibile creare la funzione UDTF per leggere un indirizzario da IFS ed è possibile scaricare i file sorgente fra i quali c’è anche IFSIO_H che contiene la definizione di molte delle API / procedure che è possibile richiamare per lavorare su IFS.
La UDTF è una funzione definita dall’utente richiamabile da SQL che ritorna una tabella.
Cercando di semplificare il più possibile le UDTF, con un’istruzione SQL è possibile richiamare una funzione associata a una procedura di un Service Program esterno (definita in fase di creazione della funzione) che può essere scritta anche in RPG e il risultato che otteniamo è una normale tabella sulla quale è possibile fare selezioni SQL. E’ inoltre possibile personalizzare i campi della tabella risultante da istruzione SQL gestendo le logiche a programma all’interno della funzione. Quindi se volessimo scrivere un campo aggiuntivo con la dicitura “CIAO” potremmo farlo facilmente modificando la procedura richiamata dall’istruzione SQL e ricreando la funzione. Non male!!!
Se siete curiosi sulle UDTF, tutto è adeguatamente documentato da Scott Klement :
https://www.scottklement.com/udtf/
Tornando alla nostra necessità di leggere un indirizzario di IFS, l’istruzione SQL da richiamare una volta creata la funzione sarà ad esempio:
Select Filename from TABLE(IFSDIR(‘/tmp’)) as t
where ACCESS_TIME < CURRENT TIMESTAMP – 90 SECONDS
In questo caso il comando permette di ottenere il nome del file da un indirizzario “tmp” su IFS selezionando solo i file con ACCESS_TIME inferiore a 90 secondi rispetto all’orario corrente. Questa istruzione funziona correttamente anche su QNTC se configurato e di seguito un esempio dove leggo la cartella condivisa “dir” sul server MyServer accedendo al QNTC :
Select Filename from TABLE(IFSDIR(‘/QNTC/MyServer/dir’)) as t
where ACCESS_TIME < CURRENT TIMESTAMP – 90 SECONDS
Questo tipo di approccio che utilizza un’istruzione SQL definita dall’utente può essere molto utile in generale, perchè può incapsulare all’interno dell’istruzione SQL anche delle logiche di business complesse rendendole facilmente fruibili ad altre applicazioni. Certo, la logica che viene invocata dalla UDTF avrà una sua complessità da gestire…
Lettura contenuto di un file su IFS o QNTC
Avevo ancora da risolvere un punto : come leggere un file da RPG ed elaborarne il contenuto. Sempre ringraziando Scott Klement ho studiato un’altra sua guida che spiega come interagire con i file in IFS : https://www.scottklement.com/rpg/ifs_ebook/ifs_ebook.html
Di seguito riporto per comodità un estratto del codice che ho scritto derivandolo dagli esempi riportati che fa riferimento ad alcune API (open, read, close) dichiarate nel file sorgente IFSIO_H per aprire, leggere e chiudere un file su IFS o QNTC.
Una cosa sulla quale bisogna prestare attenzione è come aprire i file. I file su IFS sono su un file system diverso rispetto alle librerie di IBM i e con codifiche diverse e si verificano delle situazioni di conversione di dati da gestire. L’obiettivo era aprire un file di testo per leggerne il contenuto e dopo un po’ di tentativi utilizzando il flag O_TXTDATA il contenuto era visibile e corretto.
Di seguito un estratto del codice da me utilizzato :
flags = O_RDONLY + O_TEXTDATA; // esempio -> fd = open('/ifstest/760548.txt': flags); fd = open(%trim(inpFile) : flags); if fd < 0; Msg = 'open(): failed for reading'; return; endif; // leggo dal file un numero di byte callP read(fd: %addr(stringa): %size(stringa)); // in base ai byte di confronto creo una sottostringa da controllare strTest = %subst(stringa : 1 : inpBytes); // chiudo il file description callp close(fd);
Con l’istruzione :
fd = open(%trim(inpFile)
si apre il file il cui percorso completo è presente nella variabile “inpFile” e si assegna il descrittore del file “fd”.
Tramite l’istruzione :
callP read(fd: %addr(stringa): %size(stringa));
Si legge il contenuto del file lavorando sul descrittore “fd” per n byte, pari alla dimensione della variabile stringa : %size(stringa) e la variabile stringa viene inizializzata con il contenuto degli n byte letti dal file
Tramite l’istruzione :
callp close(fd);
Viene chiuso il file lavorando sul descrittore “fd”
La possibilità di interagire nativamente con i file all’esterno del nostro sistema IBM i è una condizione importante in realtà aziendali con una infrastruttura server eterogenea anche per migliorare i processi ove possibile.
IBM punta molto su SQL per rilasciare aggiornamenti e le UDTF sono uno strumento interessante da approfondire e se possibile da inserire nella cassetta degli attrezzi di un programmatore.