[ABAP] Datei zw. Verzeichnissen des Appl.-Servers kopieren

PARAMETERS: p_s_file TYPE EPSFILNAM OBLIGATORY. " Quelldatei
PARAMETERS: p_s_dir  TYPE EPSDIRNAM OBLIGATORY. " Quelldirectory
PARAMETERS: p_t_file TYPE EPSFILNAM OBLIGATORY. " Zieldatei
PARAMETERS: p_t_dir  TYPE EPSDIRNAM OBLIGATORY. " Zieldirectory

START-OF-SELECTION.

  cl_cts_language_file_io=>copy_files_local( EXPORTING
                                               im_source_file           = p_s_file
                                               im_source_directory      = p_s_dir
                                               im_target_file           = p_t_file
                                               im_target_directory      = p_t_dir
                                               im_overwrite_mode        = 'F'
                                             EXCEPTIONS
                                               open_input_file_failed   = 1
                                               open_output_file_failed  = 2
                                               write_block_failed       = 3
                                               read_block_failed        = 4
                                               close_output_file_failed = 5
                                               OTHERS                   = 6 ).

  IF sy-subrc NE 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

[ABAP] UNIX-Pfad und -Dateinamen vom Applikationsserver aufsplitten

DATA: lv_file TYPE string VALUE '/usr/sap/test.txt'.
DATA: lv_name TYPE string.
DATA: lv_path TYPE string.

CALL FUNCTION 'TRINT_SPLIT_FILE_AND_PATH'
  EXPORTING
    full_name     = lv_file
  IMPORTING
    stripped_name = lv_name
    file_path     = lv_path
  EXCEPTIONS
    x_error       = 1
    OTHERS        = 2.
    
IF sy-subrc = 0.
  WRITE: / lv_path.
  WRITE: / lv_name.
ENDIF.

[ABAP] Dateien eines Verzeichnises auf dem Applikationsserver auflisten

Variante 1 (EPS2_GET_DIRECTORY_LISTING)

PARAMETERS: p_fdir TYPE eps2filnam DEFAULT '/usr/sap/tmp'.
PARAMETERS: p_mask TYPE eps2filnam DEFAULT '*.xml'.

START-OF-SELECTION.

  DATA: it_files TYPE STANDARD TABLE OF eps2fili WITH DEFAULT KEY.

  DATA: lv_dir_name TYPE epsf-epsdirnam.
  DATA: lv_file_counter TYPE epsf-epsfilsiz.
  DATA: lv_error_counter TYPE epsf-epsfilsiz.

* Alle Dateien im Verzeichnis lesen
* file_mask ist fehlerhaft implementiert, daher muss im Nachgang manuell gefiltert werden, s.u.
  CALL FUNCTION 'EPS2_GET_DIRECTORY_LISTING'
    EXPORTING
      iv_dir_name            = p_fdir
*     file_mask              = ''
    IMPORTING
      dir_name               = lv_dir_name
      file_counter           = lv_file_counter
      error_counter          = lv_error_counter
    TABLES
      dir_list               = it_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.
    WRITE: / lv_dir_name, lv_file_counter, lv_error_counter.

* Dateiliste Filtern
    DELETE it_files WHERE NOT name CP p_mask.

    LOOP AT it_files ASSIGNING FIELD-SYMBOL(<f>).
      WRITE: / <f>-name, <f>-size, <f>-mtim, <f>-owner, <f>-rc.
    ENDLOOP.
  ENDIF.

Variante 2 (EPS_GET_DIRECTORY_LISTING)

* nicht mehr Verwenden, da Übergabeparameter zu kurze Datentypen haben

[ABAP] Datei vom Applikationsserver binär lesen

Variante 1 (xstring)

* Dateiinhalt (Binärdatenstrom) als xstring
DATA: lv_bytes_xstr TYPE xstring.
* Pfad + Dateiname auf dem Appl.-Server
DATA(lv_file) = '/usr/sap/tmp/file.bin'.

TRY.
* Datei zum binären Lesen öffnen
    OPEN DATASET lv_file FOR INPUT IN BINARY MODE.
    IF sy-subrc = 0.
* Daten bis Dateiende lesen
      READ DATASET lv_file INTO lv_bytes_xstr.

      IF sy-subrc = 0.
        WRITE: / xstrlen( lv_bytes_xstr ), 'bytes gelesen.'.
      ELSE.
        WRITE: / 'Fehler beim Lesen.'.
      ENDIF.

* Datei schließen
      CLOSE DATASET lv_file.
    ELSE.
      WRITE: / 'Konnte Datei nicht öffnen:', lv_file.
    ENDIF.

  CATCH cx_root INTO DATA(e_txt).
    WRITE: / e_txt->get_text( ).
ENDTRY.

Variante 2 (byteweises Lesen in itab)

DATA: lv_byte TYPE x LENGTH 1.          " ein byte
DATA: it_file TYPE STANDARD TABLE OF x. " iTab mit Dateidaten
* Pfad + Dateiname auf dem Appl.-Server
DATA(lv_file) = '/usr/sap/tmp/file.bin'.

TRY.
* Datei zum binären Lesen öffnen
    OPEN DATASET lv_file FOR INPUT IN BINARY MODE.
    IF sy-subrc = 0.
* Daten bis Dateiende lesen
      DO.
* byteweise lesen
        READ DATASET lv_file INTO lv_byte.

        IF sy-subrc = 0.
* bytes an iTab anhängen, iTab kann anderweitig heruntergeladen werden
* z.B. mit cl_gui_frontend_services=>gui_download
          APPEND lv_byte TO it_file.
        ELSE.
          EXIT.
        ENDIF.
      ENDDO.

* Datei schließen
      CLOSE DATASET lv_file.
    ELSE.
      WRITE: / 'Konnte Datei nicht öffnen:', lv_file.
    ENDIF.

  CATCH cx_root INTO DATA(e_txt).
    WRITE: / e_txt->get_text( ).
ENDTRY.

[ABAP] Textdatei auf den Appl.-Server schreiben

DATA: it_file_content TYPE rsanm_file_table.
DATA: lv_file TYPE string VALUE '/usr/sap/trans/EPS/SAL/Test1.txt'.
DATA: lv_lines_written TYPE i.

it_file_content = value #( ( |Testtext 1| )
                           ( |Testtext 2| )
                           ( |Testtext 3| ) ).

TRY.
  cl_rsan_ut_appserv_file_writer=>appserver_file_write( EXPORTING
                                                          i_filename = lv_file
                                                          i_data_tab = it_file_content
                                                          i_overwrite = abap_true       " abap_false -> append, abap_true -> overwrite
                                                        IMPORTING
                                                          e_lines_written = lv_lines_written ).

  WRITE: / 'Lines written: ', lv_lines_written.

CATCH cx_root INTO DATA(e_text).
  WRITE: / e_text->get_text( ).
ENDTRY.

[ABAP] Textdatei vom Appl.-Server lesen

DATA: it_file_content TYPE rsanm_file_table.
DATA: lv_file TYPE string VALUE '/usr/sap/Test.txt'.

TRY.
    cl_rsan_ut_appserv_file_reader=>appserver_file_read( EXPORTING
                                                           i_filename = lv_file
                                                         CHANGING
                                                           c_data_tab = it_file_content ).

    LOOP AT it_file_content ASSIGNING FIELD-SYMBOL(<fs_line>).
      WRITE: / <fs_line>.
    ENDLOOP.

  CATCH cx_root INTO DATA(e_text).
    WRITE: / e_text->get_text( ).
ENDTRY.

[ABAP] Prüfen, ob ein Verzeichnis auf dem Applikationsserver existiert / schreibbar ist

DATA: lv_dir TYPE char128 VALUE '/usr/sap'.
  
CALL FUNCTION 'PFL_CHECK_DIRECTORY'
  EXPORTING
    write_check                 = abap_true
    directory_long              = lv_dir    " darf kein TYPE string sein, sonst Exception
  EXCEPTIONS
    pfl_dir_not_exist           = 1
    pfl_permission_denied       = 2
    pfl_cant_build_dataset_name = 3
    pfl_file_not_exist          = 4
    pfl_authorization_missing   = 5
    OTHERS                      = 6.

IF sy-subrc = 0.

ENDIF.

[ABAP] Prüfen, ob eine Datei auf dem Applikationsserver existiert (FileExists)

Variante 1 (OPEN DATASET, ohne Berechtigungsprüfung)

DATA(lv_file) = '/usr/sap/tmp/file.txt'.

* Datei auf dem Appl.-Server vorhanden -> Datei testweise öffnen und prüfen
OPEN DATASET lv_file FOR INPUT IN TEXT MODE ENCODING DEFAULT IGNORING CONVERSION ERRORS.

IF sy-subrc = 0.
  CLOSE DATASET lv_file.

  WRITE: / |File exists.|.
ELSE.
  WRITE: / |File doesn't exist.|.
ENDIF.

Variante 2 (PFL_CHECK_OS_FILE_EXISTENCE mit Berechtigungsprüfung für S_RZL_ADM ACTVT 01)

            
DATA: lv_file TYPE pfebackuppro VALUE '/usr/sap/tmp/file.txt'.
DATA: lv_exists TYPE abap_bool.

CALL FUNCTION 'PFL_CHECK_OS_FILE_EXISTENCE'
  EXPORTING
    long_filename         = lv_file
  IMPORTING
    file_exists           = lv_exists
  EXCEPTIONS
    authorization_missing = 1
    OTHERS                = 2.

IF sy-subrc = 0.
  IF lv_exists = abap_true.
    WRITE: / |File exists.|.
  ELSE.
    WRITE: / |File doesn't exist.|.
  ENDIF.
ELSE.
  WRITE: / 'Error:', sy-subrc.
ENDIF.

[ABAP] Beliebige Dateien zu einer Zipdatei hinzufügen

TYPES: BEGIN OF bin_file,                          " Typ für Binärdatei mit Meta-Infos für das Zipfile
         name TYPE string,
         size TYPE i,
         data TYPE solix_tab,
       END OF bin_file.

DATA: lv_filename TYPE string.                     " Dateiname für FileOpen/FileSave
DATA: wa_file TYPE bin_file.                       " Binärdatei mit Meta-Infos für das Zipfile
DATA: it_binfiles TYPE STANDARD TABLE OF bin_file. " unkomprimierter Stream (Tabelle mit Dateien zum Zippen)
DATA: lv_path TYPE string.

START-OF-SELECTION.
* ZIP-Objekt erzeugen
  DATA(o_zip) = NEW cl_abap_zip( ).

  DATA: it_sel_filetab TYPE filetable.
  DATA: ret_code TYPE i.
  DATA: lv_action TYPE i.
* FileOpen-Dialog für Dateiauswahl anzeigen
* Mehrfachselektion möglich
  cl_gui_frontend_services=>file_open_dialog( EXPORTING
                                                window_title   = 'Dateien zum Komprimieren auswählen'
                                                multiselection = abap_true
                                              CHANGING
                                                file_table     = it_sel_filetab
                                                rc             = ret_code    " Anzahl ausgewählte Dateien, -1 bei Fehler
                                                user_action    = lv_action ).

  IF lv_action = cl_gui_frontend_services=>action_ok.

* Ausgewählte Dateien durchgehen
    LOOP AT it_sel_filetab INTO DATA(wa_sel_file).

      WRITE: / |Datei hinzugefügt: { wa_sel_file-filename }|.

* Dateien auf den Appl.-Server hochladen
      cl_gui_frontend_services=>gui_upload( EXPORTING
                                              filename   = |{ wa_sel_file-filename }|
                                              filetype   = 'BIN'
                                            IMPORTING
                                              filelength = wa_file-size
                                            CHANGING
                                              data_tab   = wa_file-data ).

* Pfad + Dateinamen aufsplitten
      CALL FUNCTION 'SO_SPLIT_FILE_AND_PATH'
        EXPORTING
          full_name     = wa_sel_file-filename
        IMPORTING
          file_path     = lv_path
          stripped_name = wa_file-name
        EXCEPTIONS
          x_error       = 1
          OTHERS        = 2.

* Datei zum Stream hinzufügen
      APPEND wa_file TO it_binfiles.

    ENDLOOP.

    ULINE.

    DATA: lv_xstring TYPE xstring.
* unkomprimierte Daten zum Zip-File hinzufügen
    LOOP AT it_binfiles INTO wa_file.

* jeden Datei-Stream binär zu xstring wandeln
      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = wa_file-size
        IMPORTING
          buffer       = lv_xstring
        TABLES
          binary_tab   = wa_file-data.

      o_zip->add( name    = wa_file-name
                  content = lv_xstring ).

    ENDLOOP.

* Daten komprimieren
    DATA(lv_zip) = o_zip->save( ).

    DATA: lv_zip_size TYPE i.
    DATA: it_zip_bin_data TYPE STANDARD TABLE OF raw255.

* xstring mit Zip-Daten zu binär rückwandeln
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        = lv_zip
      IMPORTING
        output_length = lv_zip_size
      TABLES
        binary_tab    = it_zip_bin_data.

    DATA: lv_dest_filepath TYPE string.

* SaveFile-Dialog aufrufen
    cl_gui_frontend_services=>file_save_dialog( EXPORTING
                                                  window_title         = 'Zipdatei speichern'
                                                  file_filter          = '(*.zip)|*.zip|'
                                                CHANGING
                                                  filename             = lv_filename
                                                  path                 = lv_path
                                                  fullpath             = lv_dest_filepath ).

* Zipdatei vom Appl-Server auf den lokalen Pfad speichern
    cl_gui_frontend_services=>gui_download( EXPORTING
                                              filename                = lv_dest_filepath
                                              filetype                = 'BIN'
                                              bin_filesize            = lv_zip_size
                                            CHANGING
                                              data_tab                = it_zip_bin_data ).

    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ELSE.
      WRITE: / |Zipdatei erfolgreich unter { lv_dest_filepath } gespeichert.|.
    ENDIF.
  ENDIF.