Opérations sur fichiers ABAP : OPEN DATASET, READ, TRANSFER

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

Les opérations sur fichiers permettent de lire et d’écrire des fichiers sur le serveur d’applications SAP. Les commandes OPEN DATASET, READ DATASET, TRANSFER et CLOSE DATASET constituent la base du traitement de fichiers en ABAP.

Commandes de base

CommandeDescription
OPEN DATASETOuvrir un fichier
READ DATASETLire des données d’un fichier
TRANSFERÉcrire des données dans un fichier
CLOSE DATASETFermer un fichier
DELETE DATASETSupprimer un fichier

Syntaxe

Ouvrir un fichier

OPEN DATASET <nom_fichier>
FOR { INPUT | OUTPUT | APPENDING | UPDATE }
IN { TEXT MODE | BINARY MODE | LEGACY TEXT MODE }
[ ENCODING { DEFAULT | UTF-8 | NON-UNICODE } ]
[ WITH { SMART | NATIVE | UNIX | WINDOWS } LINEFEED ]
[ MESSAGE <message> ].

Lire/écrire un fichier

READ DATASET <nom_fichier> INTO <données> [ LENGTH <longueur> ].
TRANSFER <données> TO <nom_fichier> [ LENGTH <longueur> ].

Fermer/supprimer un fichier

CLOSE DATASET <nom_fichier>.
DELETE DATASET <nom_fichier>.

Exemples

1. Écrire un fichier texte

DATA: lv_file TYPE string VALUE '/tmp/output.txt',
lv_message TYPE string.
" Ouvrir le fichier en écriture
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
MESSAGE lv_message.
IF sy-subrc = 0.
" Écrire des lignes
TRANSFER 'Ligne 1: Bonjour le monde' TO lv_file.
TRANSFER 'Ligne 2: ABAP est génial' TO lv_file.
TRANSFER 'Ligne 3: Fin du fichier' TO lv_file.
CLOSE DATASET lv_file.
WRITE: / 'Fichier écrit avec succès'.
ELSE.
WRITE: / 'Erreur:', lv_message.
ENDIF.

2. Lire un fichier texte

DATA: lv_file TYPE string VALUE '/tmp/input.txt',
lv_line TYPE string.
OPEN DATASET lv_file FOR INPUT IN TEXT MODE
ENCODING UTF-8.
IF sy-subrc = 0.
" Lire ligne par ligne
DO.
READ DATASET lv_file INTO lv_line.
IF sy-subrc <> 0.
EXIT. " Fin du fichier
ENDIF.
WRITE: / lv_line.
ENDDO.
CLOSE DATASET lv_file.
ELSE.
WRITE: / 'Le fichier n''a pas pu être ouvert'.
ENDIF.

3. Lire un fichier dans une table

DATA: lv_file TYPE string VALUE '/tmp/data.txt',
lv_line TYPE string,
lt_lines TYPE TABLE OF string.
OPEN DATASET lv_file FOR INPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc = 0.
DO.
READ DATASET lv_file INTO lv_line.
IF sy-subrc <> 0.
EXIT.
ENDIF.
APPEND lv_line TO lt_lines.
ENDDO.
CLOSE DATASET lv_file.
" Traitement
WRITE: / 'Lignes lues:', lines( lt_lines ).
ENDIF.

4. Écrire une table dans un fichier

DATA: lv_file TYPE string VALUE '/tmp/export.txt',
lt_lines TYPE TABLE OF string.
lt_lines = VALUE #(
( `Nom;Age;Ville` )
( `Max;30;Berlin` )
( `Anna;25;Munich` )
( `Peter;35;Hambourg` )
).
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc = 0.
LOOP AT lt_lines INTO DATA(lv_line).
TRANSFER lv_line TO lv_file.
ENDLOOP.
CLOSE DATASET lv_file.
WRITE: / 'Exporté:', lines( lt_lines ), 'lignes'.
ENDIF.

5. Traiter un fichier CSV

TYPES: BEGIN OF ty_customer,
name TYPE string,
age TYPE i,
city TYPE string,
END OF ty_customer.
DATA: lv_file TYPE string VALUE '/tmp/customers.csv',
lv_line TYPE string,
lt_customers TYPE TABLE OF ty_customer,
lt_fields TYPE TABLE OF string.
OPEN DATASET lv_file FOR INPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc = 0.
" Ignorer la ligne d'en-tête
READ DATASET lv_file INTO lv_line.
" Lire les lignes de données
DO.
READ DATASET lv_file INTO lv_line.
IF sy-subrc <> 0.
EXIT.
ENDIF.
" Diviser la ligne
SPLIT lv_line AT ';' INTO TABLE lt_fields.
IF lines( lt_fields ) >= 3.
APPEND VALUE ty_customer(
name = lt_fields[ 1 ]
age = CONV #( lt_fields[ 2 ] )
city = lt_fields[ 3 ]
) TO lt_customers.
ENDIF.
ENDDO.
CLOSE DATASET lv_file.
ENDIF.
" Afficher le résultat
LOOP AT lt_customers INTO DATA(ls_cust).
WRITE: / ls_cust-name, ls_cust-age, ls_cust-city.
ENDLOOP.

6. Créer une exportation CSV

DATA: lv_file TYPE string VALUE '/tmp/export.csv',
lv_line TYPE string.
DATA: lt_orders TYPE TABLE OF ty_order.
" Données de test
lt_orders = VALUE #(
( id = 1 customer = 'Müller' amount = '100.50' )
( id = 2 customer = 'Schmidt' amount = '250.00' )
( id = 3 customer = 'Weber' amount = '75.25' )
).
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc = 0.
" Écrire l'en-tête
TRANSFER 'ID;Client;Montant' TO lv_file.
" Lignes de données
LOOP AT lt_orders INTO DATA(ls_order).
lv_line = |{ ls_order-id };{ ls_order-customer };{ ls_order-amount }|.
TRANSFER lv_line TO lv_file.
ENDLOOP.
CLOSE DATASET lv_file.
ENDIF.

7. Lire un fichier binaire

DATA: lv_file TYPE string VALUE '/tmp/image.png',
lv_data TYPE xstring,
lv_buffer TYPE x LENGTH 1024,
lv_length TYPE i.
OPEN DATASET lv_file FOR INPUT IN BINARY MODE.
IF sy-subrc = 0.
DO.
READ DATASET lv_file INTO lv_buffer LENGTH lv_length.
IF sy-subrc <> 0.
EXIT.
ENDIF.
" Ajouter les données
CONCATENATE lv_data lv_buffer(lv_length) INTO lv_data IN BYTE MODE.
ENDDO.
CLOSE DATASET lv_file.
WRITE: / 'Lu:', xstrlen( lv_data ), 'octets'.
ENDIF.

8. Écrire un fichier binaire

DATA: lv_file TYPE string VALUE '/tmp/output.bin',
lv_data TYPE xstring.
" Données binaires (par ex. de la DB ou traitement)
lv_data = 'A1B2C3D4E5F6'.
OPEN DATASET lv_file FOR OUTPUT IN BINARY MODE.
IF sy-subrc = 0.
TRANSFER lv_data TO lv_file.
CLOSE DATASET lv_file.
ENDIF.

9. Ajouter à un fichier (APPENDING)

DATA: lv_file TYPE string VALUE '/tmp/log.txt',
lv_line TYPE string.
" Ajouter date/heure au log
lv_line = |{ sy-datum DATE = ISO } { sy-uzeit TIME = ISO }: Nouvelle entrée|.
OPEN DATASET lv_file FOR APPENDING IN TEXT MODE ENCODING UTF-8.
IF sy-subrc = 0.
TRANSFER lv_line TO lv_file.
CLOSE DATASET lv_file.
ENDIF.

10. Vérifier et supprimer un fichier

DATA: lv_file TYPE string VALUE '/tmp/temp.txt'.
" Vérifier si le fichier existe (en l'ouvrant)
OPEN DATASET lv_file FOR INPUT IN TEXT MODE ENCODING DEFAULT.
IF sy-subrc = 0.
CLOSE DATASET lv_file.
WRITE: / 'Le fichier existe'.
" Supprimer le fichier
DELETE DATASET lv_file.
IF sy-subrc = 0.
WRITE: / 'Fichier supprimé'.
ENDIF.
ELSE.
WRITE: / 'Le fichier n''existe pas'.
ENDIF.

11. Lire un répertoire

DATA: lv_dir TYPE string VALUE '/tmp/',
lt_files TYPE TABLE OF string,
lv_filename TYPE string.
" Ouvrir le répertoire
CALL FUNCTION 'EPS_GET_DIRECTORY_LISTING"
EXPORTING
dir_name = CONV eps2path( lv_dir )
TABLES
dir_list = lt_files
EXCEPTIONS
invalid_eps_subdir = 1
sapgparam_failed = 2
build_directory_failed = 3
no_authorization = 4
read_directory_failed = 5
too_many_read_errors = 6
empty_directory_list = 7
OTHERS = 8.
IF sy-subrc = 0.
LOOP AT lt_files INTO lv_filename.
WRITE: / lv_filename.
ENDLOOP.
ENDIF.

12. Fichier avec message d’erreur

DATA: lv_file TYPE string VALUE '/nonexistent/path/file.txt',
lv_message TYPE string.
OPEN DATASET lv_file FOR INPUT IN TEXT MODE
ENCODING UTF-8
MESSAGE lv_message.
IF sy-subrc <> 0.
WRITE: / 'Erreur lors de l''ouverture:'.
WRITE: / lv_message.
WRITE: / 'Code retour:', sy-subrc.
ENDIF.

13. Modes de saut de ligne

" Saut de ligne Unix (LF)
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
WITH UNIX LINEFEED.
" Saut de ligne Windows (CRLF)
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
WITH WINDOWS LINEFEED.
" Automatique (dépend du serveur)
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
WITH NATIVE LINEFEED.
" Smart: Écriture comme Native, lecture détecte automatiquement
OPEN DATASET lv_file FOR INPUT IN TEXT MODE
ENCODING UTF-8
WITH SMART LINEFEED.

14. Positionnement dans un fichier

DATA: lv_file TYPE string VALUE '/tmp/data.bin',
lv_data TYPE x LENGTH 100,
lv_pos TYPE i.
OPEN DATASET lv_file FOR UPDATE IN BINARY MODE.
IF sy-subrc = 0.
" Obtenir la position
GET DATASET lv_file POSITION lv_pos.
WRITE: / 'Position actuelle:', lv_pos.
" Aller à une position
SET DATASET lv_file POSITION 100.
" Lire à partir de la position 100
READ DATASET lv_file INTO lv_data.
CLOSE DATASET lv_file.
ENDIF.

15. Traiter efficacement des fichiers volumineux

CONSTANTS: c_buffer_size TYPE i VALUE 8192.
DATA: lv_file TYPE string VALUE '/tmp/large_file.txt',
lv_buffer TYPE string,
lv_count TYPE i.
OPEN DATASET lv_file FOR INPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc = 0.
DO.
READ DATASET lv_file INTO lv_buffer.
IF sy-subrc <> 0.
EXIT.
ENDIF.
lv_count = lv_count + 1.
" Traitement sans sauvegarder toutes les lignes
" process_line( lv_buffer ).
" Afficher la progression (toutes les 10000 lignes)
IF lv_count MOD 10000 = 0.
WRITE: / 'Traité:', lv_count, 'lignes'.
ENDIF.
ENDDO.
CLOSE DATASET lv_file.
WRITE: / 'Total:', lv_count, 'lignes'.
ENDIF.

16. Créer un fichier temporaire

DATA: lv_temp_file TYPE string,
lv_guid TYPE sysuuid_c32.
" Générer un nom de fichier unique
lv_guid = cl_system_uuid=>create_uuid_c32_static( ).
lv_temp_file = |/tmp/temp_{ lv_guid }.txt|.
" Utiliser le fichier temporaire
OPEN DATASET lv_temp_file FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
TRANSFER 'Données temporaires' TO lv_temp_file.
CLOSE DATASET lv_temp_file.
" ... Traitement ...
" Nettoyage
DELETE DATASET lv_temp_file.

Options d’encodage

EncodageDescription
DEFAULTStandard système
UTF-8Unicode (recommandé)
NON-UNICODELegacy, non-Unicode

Valeurs sy-subrc

ValeurSignification
0Succès
4Fin du fichier (READ)
8Erreur (fichier non trouvé, pas d’autorisation)

Alternative ABAP Cloud

" Dans ABAP Cloud: Interface FILE non disponible
" À la place: CL_ABAP_FILE_UTILITIES ou XCO
" Exemple avec XCO (Cloud)
DATA(lo_file) = xco_cp=>file( '/tmp/test.txt' ).
" Vérifier s'il existe
IF lo_file->exists( ).
" Lire
DATA(lv_content) = lo_file->read( )->as_string( ).
ENDIF.

Remarques importantes / Bonnes pratiques

  • Toujours appeler CLOSE DATASET – même en cas d’erreurs (TRY-FINALLY).
  • Utiliser UTF-8 comme encodage pour les fichiers modernes.
  • Utiliser MESSAGE pour des messages d’erreur significatifs.
  • sy-subrc = 4 lors du READ signifie fin du fichier (EOF).
  • APPENDING pour ajouter à des fichiers existants.
  • Traiter les fichiers volumineux ligne par ligne au lieu de les charger complètement.
  • Vérifier les autorisations (S_DATASET) pour l’accès aux fichiers.
  • Toujours spécifier les chemins en absolu (pas relatif).
  • Dans ABAP Cloud, les opérations sur fichiers sont limitées – utiliser XCO.
  • Fichiers binaires pour les contenus non texte (images, PDF).