ABAP Dateioperationen: OPEN DATASET, READ, TRANSFER

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Dateioperationen ermöglichen das Lesen und Schreiben von Dateien auf dem SAP-Applikationsserver. Die Befehle OPEN DATASET, READ DATASET, TRANSFER und CLOSE DATASET bilden die Grundlage für Dateiverarbeitung in ABAP.

Grundbefehle

BefehlBeschreibung
OPEN DATASETDatei öffnen
READ DATASETDaten aus Datei lesen
TRANSFERDaten in Datei schreiben
CLOSE DATASETDatei schließen
DELETE DATASETDatei löschen

Syntax

Datei öffnen

OPEN DATASET <dateiname>
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 <nachricht> ].

Datei lesen/schreiben

READ DATASET <dateiname> INTO <daten> [ LENGTH <länge> ].
TRANSFER <daten> TO <dateiname> [ LENGTH <länge> ].

Datei schließen/löschen

CLOSE DATASET <dateiname>.
DELETE DATASET <dateiname>.

Beispiele

1. Textdatei schreiben

DATA: lv_file TYPE string VALUE '/tmp/output.txt',
lv_message TYPE string.
" Datei zum Schreiben öffnen
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
MESSAGE lv_message.
IF sy-subrc = 0.
" Zeilen schreiben
TRANSFER 'Zeile 1: Hallo Welt' TO lv_file.
TRANSFER 'Zeile 2: ABAP ist toll' TO lv_file.
TRANSFER 'Zeile 3: Ende der Datei' TO lv_file.
CLOSE DATASET lv_file.
WRITE: / 'Datei erfolgreich geschrieben'.
ELSE.
WRITE: / 'Fehler:', lv_message.
ENDIF.

2. Textdatei lesen

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.
" Zeilenweise lesen
DO.
READ DATASET lv_file INTO lv_line.
IF sy-subrc <> 0.
EXIT. " Ende der Datei
ENDIF.
WRITE: / lv_line.
ENDDO.
CLOSE DATASET lv_file.
ELSE.
WRITE: / 'Datei konnte nicht geöffnet werden'.
ENDIF.

3. Datei in Tabelle einlesen

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.
" Verarbeitung
WRITE: / 'Gelesene Zeilen:', lines( lt_lines ).
ENDIF.

4. Tabelle in Datei schreiben

DATA: lv_file TYPE string VALUE '/tmp/export.txt',
lt_lines TYPE TABLE OF string.
lt_lines = VALUE #(
( `Name;Alter;Stadt` )
( `Max;30;Berlin` )
( `Anna;25;München` )
( `Peter;35;Hamburg` )
).
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: / 'Exportiert:', lines( lt_lines ), 'Zeilen'.
ENDIF.

5. CSV-Datei verarbeiten

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.
" Kopfzeile überspringen
READ DATASET lv_file INTO lv_line.
" Datenzeilen lesen
DO.
READ DATASET lv_file INTO lv_line.
IF sy-subrc <> 0.
EXIT.
ENDIF.
" Zeile splitten
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.
" Ergebnis anzeigen
LOOP AT lt_customers INTO DATA(ls_cust).
WRITE: / ls_cust-name, ls_cust-age, ls_cust-city.
ENDLOOP.

6. CSV-Export erstellen

DATA: lv_file TYPE string VALUE '/tmp/export.csv',
lv_line TYPE string.
DATA: lt_orders TYPE TABLE OF ty_order.
" Testdaten
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.
" Header schreiben
TRANSFER 'ID;Kunde;Betrag' TO lv_file.
" Datenzeilen
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. Binärdatei lesen

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.
" Daten anhängen
CONCATENATE lv_data lv_buffer(lv_length) INTO lv_data IN BYTE MODE.
ENDDO.
CLOSE DATASET lv_file.
WRITE: / 'Gelesen:', xstrlen( lv_data ), 'Bytes'.
ENDIF.

8. Binärdatei schreiben

DATA: lv_file TYPE string VALUE '/tmp/output.bin',
lv_data TYPE xstring.
" Binärdaten (z.B. aus DB oder Verarbeitung)
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. An Datei anhängen (APPENDING)

DATA: lv_file TYPE string VALUE '/tmp/log.txt',
lv_line TYPE string.
" Datum/Zeit zum Log hinzufügen
lv_line = |{ sy-datum DATE = ISO } { sy-uzeit TIME = ISO }: Neuer Eintrag|.
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. Datei prüfen und löschen

DATA: lv_file TYPE string VALUE '/tmp/temp.txt'.
" Prüfen ob Datei existiert (durch Öffnen)
OPEN DATASET lv_file FOR INPUT IN TEXT MODE ENCODING DEFAULT.
IF sy-subrc = 0.
CLOSE DATASET lv_file.
WRITE: / 'Datei existiert'.
" Datei löschen
DELETE DATASET lv_file.
IF sy-subrc = 0.
WRITE: / 'Datei gelöscht'.
ENDIF.
ELSE.
WRITE: / 'Datei existiert nicht'.
ENDIF.

11. Verzeichnis lesen

DATA: lv_dir TYPE string VALUE '/tmp/',
lt_files TYPE TABLE OF string,
lv_filename TYPE string.
" Verzeichnis öffnen
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. Datei mit Fehlermeldung

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: / 'Fehler beim Öffnen:'.
WRITE: / lv_message.
WRITE: / 'Return Code:', sy-subrc.
ENDIF.

13. Zeilenumbruch-Modi

" Unix-Zeilenumbruch (LF)
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
WITH UNIX LINEFEED.
" Windows-Zeilenumbruch (CRLF)
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
WITH WINDOWS LINEFEED.
" Automatisch (abhängig vom Server)
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE
ENCODING UTF-8
WITH NATIVE LINEFEED.
" Smart: Schreiben wie Native, Lesen erkennt automatisch
OPEN DATASET lv_file FOR INPUT IN TEXT MODE
ENCODING UTF-8
WITH SMART LINEFEED.

14. Positionierung in Datei

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.
" Position ermitteln
GET DATASET lv_file POSITION lv_pos.
WRITE: / 'Aktuelle Position:', lv_pos.
" An Position springen
SET DATASET lv_file POSITION 100.
" Lesen ab Position 100
READ DATASET lv_file INTO lv_data.
CLOSE DATASET lv_file.
ENDIF.

15. Große Dateien effizient verarbeiten

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.
" Verarbeitung ohne Speichern aller Zeilen
" process_line( lv_buffer ).
" Fortschritt anzeigen (alle 10000 Zeilen)
IF lv_count MOD 10000 = 0.
WRITE: / 'Verarbeitet:', lv_count, 'Zeilen'.
ENDIF.
ENDDO.
CLOSE DATASET lv_file.
WRITE: / 'Gesamt:', lv_count, 'Zeilen'.
ENDIF.

16. Temporäre Datei erstellen

DATA: lv_temp_file TYPE string,
lv_guid TYPE sysuuid_c32.
" Eindeutigen Dateinamen generieren
lv_guid = cl_system_uuid=>create_uuid_c32_static( ).
lv_temp_file = |/tmp/temp_{ lv_guid }.txt|.
" Temporäre Datei verwenden
OPEN DATASET lv_temp_file FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
TRANSFER 'Temporäre Daten' TO lv_temp_file.
CLOSE DATASET lv_temp_file.
" ... Verarbeitung ...
" Aufräumen
DELETE DATASET lv_temp_file.

Encoding-Optionen

EncodingBeschreibung
DEFAULTSystem-Standard
UTF-8Unicode (empfohlen)
NON-UNICODELegacy, nicht-Unicode

sy-subrc Werte

WertBedeutung
0Erfolgreich
4Ende der Datei (READ)
8Fehler (Datei nicht gefunden, keine Berechtigung)

ABAP Cloud Alternative

" In ABAP Cloud: FILE-Interface nicht verfügbar
" Stattdessen: CL_ABAP_FILE_UTILITIES oder XCO
" Beispiel mit XCO (Cloud)
DATA(lo_file) = xco_cp=>file( '/tmp/test.txt' ).
" Prüfen ob existiert
IF lo_file->exists( ).
" Lesen
DATA(lv_content) = lo_file->read( )->as_string( ).
ENDIF.

Wichtige Hinweise / Best Practice

  • CLOSE DATASET immer aufrufen – auch bei Fehlern (TRY-FINALLY).
  • UTF-8 als Encoding für moderne Dateien verwenden.
  • MESSAGE-Zusatz für aussagekräftige Fehlermeldungen.
  • sy-subrc = 4 bei READ bedeutet Ende der Datei (EOF).
  • APPENDING zum Anhängen an bestehende Dateien.
  • Große Dateien zeilenweise verarbeiten statt komplett laden.
  • Berechtigungen (S_DATASET) für Dateizugriff prüfen.
  • Pfade immer absolut angeben (nicht relativ).
  • In ABAP Cloud sind Dateioperationen eingeschränkt – XCO verwenden.
  • Binärdateien für nicht-Text-Inhalte (Bilder, PDFs).