Copyright 2022 - BV TallVision IT

How can you get a directory listing from Unix/WindowsNT backend files ? Or presentation server files ? First of all: you'll need to differentiate between presentation server files and server files. Then the server type can be important, Unix or Windows NT ? Here's an overview of getting directory listings or file listings for each.

Presentation server (the PC of the end user)

Class CL_GUI_FRONTEND_SERVICES holds a method DIRECTORY_LIST_FILES which can find your files. Feed it a path and an optional mask for the files and it returns a table with filenames.

You can use a function module RZL_READ_DIR_LOCAL that returns a list of filenames and sizes. This module does not indicate whether the "file" is in fact a directory. However: the size of the file or directory is made available and directories have a size of 0. So if you are happy to ignore empty files as if they were folders, use the size.

There is also a module RZL_READ_DIR_REMOTE which can reach out to other (SAP) servers for a name listing. (Presentation server) IWB_DIRECTORY_GET also lists files with a full path, for a given path. Then there is the TMP_GUI_DIRECTORY_LIST_FILES which returns a file listings table and a directory listings table separately.

Server - Windows NT

Function module EPS_GET_DIRECTORY_LISTING is a good candidate. EPS2_GET_DIRECTORY_LISTING does the same thing as EPS_GET_DIRECTORY_LISTING BUT returns the file names with up to 200 chars.

Server - Unix

This is a nice (but old)example that returns file and directory info based on C-routines. For this...Routines C_DIR_READ_START, C_DIR_READ_NEXT and C_DIR_READ_FINISH will guide you through a directory listing, which only works for a Unix backend. It does work with a lot of file/directory detail, which is why it can be very handy. Data definition for the example

* Layout for use with calls to read directory
    TYPES: BEGIN OF ty_dir_entry,
            name(75),        " name of entry
            type(15),        " type of entry
            len(4) TYPE p DECIMALS 0,   " length in bytes
            owner(8),        " owner of the entry
            mtime(6) TYPE p DECIMALS 0, "seconds since 1st of Jan 1970
            mode(9),         " like "rwx-r-x--x": protection mode.
            subrc(4),
            errno(3),
            errmsg(40),
          END OF ty_dir_entry,
          ty_dir_entry_tt TYPE STANDARD TABLE OF ty_dir_entry.
    DATA: gt_listing type ty_dir_entry_tt. 

The main program for initialising and going through a directory listing.

    DATA: lw_dir_entry TYPE ty_dir_entry,
          lv_file_name_length LIKE sy-dbcnt,
          lv_output_file TYPE char80,
          lv_directory TYPE edipo-outputdir.

    CLEAR: gt_listing[].
    returncode = 4. "Default assumption
    CALL 'C_DIR_READ_FINISH'
        ID 'ERRNO'  FIELD lw_dir_entry-errno
        ID 'ERRMSG' FIELD lw_dir_entry-errmsg.

    lv_directory = directory.
* Position the read in the directory we want
    CALL 'C_DIR_READ_START' ID 'DIR'    FIELD lv_directory
                            ID 'FILE'   FIELD '*'
                            ID 'ERRNO'  FIELD lw_dir_entry-errno
                            ID 'ERRMSG' FIELD lw_dir_entry-errmsg.
    CHECK sy-subrc = 0. "If this step fails: simply stop processing

* Find the files
    DO.
      CLEAR lw_dir_entry.
      CALL 'C_DIR_READ_NEXT'
        ID 'TYPE'   FIELD lw_dir_entry-type
        ID 'NAME'   FIELD lw_dir_entry-name
        ID 'LEN'    FIELD lw_dir_entry-len
        ID 'OWNER'  FIELD lw_dir_entry-owner
        ID 'MTIME'  FIELD lw_dir_entry-mtime
        ID 'MODE'   FIELD lw_dir_entry-mode
        ID 'ERRNO'  FIELD lw_dir_entry-errno
        ID 'ERRMSG' FIELD lw_dir_entry-errmsg.

      IF sy-subrc <> 0 AND lw_dir_entry-name IS INITIAL.
        EXIT.   "End of the listing has been reached
      ELSEIF sy-subrc = 3. "RC=3 File too big to fit in v_file-len
        CONTINUE.
      ELSEIF lw_dir_entry-name IS INITIAL.
        CONTINUE.
      ENDIF.
      APPEND lw_dir_entry TO gt_listing.

    ENDDO.

    CALL 'C_DIR_READ_FINISH'
        ID 'ERRNO'  FIELD lw_dir_entry-errno
        ID 'ERRMSG' FIELD lw_dir_entry-errmsg.

    returncode = 0.

The internal table gt_listing will hold the list of (non-empty) files.

The above method in a ready-to-use implementation block and method: 

  PUBLIC SECTION.
    CONSTANTS: co_all(1) TYPE c VALUE 'A',
               co_directories_only(1) TYPE c VALUE 'D',
               co_files_only(1) TYPE c VALUE 'F'.

    TYPES: BEGIN OF ty_dir_entry,
            name(75),        " name of entry
            type(15),        " type of entry
            len(4) TYPE p DECIMALS 0,   " length in bytes
            owner(8),        " owner of the entry
            mtime(6) TYPE p DECIMALS 0, " last mod. date, seconds since 1970
            mode(9),         " like "rwx-r-x--x": protection mode.
            subrc(4),
            errno(3),
            errmsg(40),
          END OF ty_dir_entry,
          ty_dir_entry_tt TYPE STANDARD TABLE OF ty_dir_entry.

  CLASS-METHODS:
      get_directory_listing
        IMPORTING directory TYPE any
                  filter TYPE c DEFAULT 'A' "A=All, D=Directory only, F=File only
        EXPORTING listing TYPE ty_dir_entry_tt
                  returncode TYPE sy-subrc,
* This method fetches a listing of directories and/or files from the path specified.
* The operation is done on a Unix server and a list of file/directory details is
* returned, along with a returncode (e.g. path not valid).
*----------------------------------------------------------------------
  METHOD get_directory_listing.
*----------------------------------------------------------------------

    DATA: lw_dir_entry TYPE ty_dir_entry,
          lv_directory TYPE c length 200.

    CLEAR: listing[].
    returncode = 4. "Default assumption: if we don't make it to the end - it's an error

    CALL 'C_DIR_READ_FINISH'
        ID 'ERRNO'  FIELD lw_dir_entry-errno
        ID 'ERRMSG' FIELD lw_dir_entry-errmsg.

    lv_directory = directory.
* Position the read in the directory we want
    CALL 'C_DIR_READ_START' ID 'DIR'    FIELD lv_directory
                            ID 'FILE'   FIELD '*'
                            ID 'ERRNO'  FIELD lw_dir_entry-errno
                            ID 'ERRMSG' FIELD lw_dir_entry-errmsg.
    CHECK lw_dir_entry-errno IS INITIAL.

* Find the files
    DO.
      CLEAR lw_dir_entry.
      CALL 'C_DIR_READ_NEXT'
        ID 'TYPE'   FIELD lw_dir_entry-type
        ID 'NAME'   FIELD lw_dir_entry-name
        ID 'LEN'    FIELD lw_dir_entry-len
        ID 'OWNER'  FIELD lw_dir_entry-owner
        ID 'MTIME'  FIELD lw_dir_entry-mtime
        ID 'MODE'   FIELD lw_dir_entry-mode
        ID 'ERRNO'  FIELD lw_dir_entry-errno
        ID 'ERRMSG' FIELD lw_dir_entry-errmsg.

      IF sy-subrc = 1.
        EXIT.   "End of the listing has been reached
      ELSEIF sy-subrc = 3. "RC=3 File too big to fit in v_file-len
        CONTINUE.
      ELSEIF lw_dir_entry-name IS INITIAL.
        CONTINUE.
      ENDIF.
* Check the type against the filter settings:
      IF ( filter = co_directories_only AND lw_dir_entry-type(3) = 'dir' AND
           lw_dir_entry-name <> '.' AND lw_dir_entry-name <> '..' ) OR
         ( filter = co_files_only AND lw_dir_entry-type(4) = 'file' ) OR
         ( filter = co_all ).
        APPEND lw_dir_entry TO listing.
      ENDIF.
    ENDDO.

    CALL 'C_DIR_READ_FINISH'
        ID 'ERRNO'  FIELD lw_dir_entry-errno
        ID 'ERRMSG' FIELD lw_dir_entry-errmsg.
    CHECK lw_dir_entry-errno IS INITIAL.
    returncode = 0.

  ENDMETHOD.                    "get_directory_listing

Server - Unix - alternative

There's also a short and sweet method using CALL 'SYSTEM' at your disposal (in this example for directory /usr/).

DATA:
  lv_command type char200,
  lt_result_output TYPE TABLE OF char200.

concatenate 'ls -l'  "Unix command: LiSt
  '/usr/' into lv_command separated by space.
CALL 'SYSTEM' ID 'COMMAND' FIELD lv_command
              ID 'TAB'     FIELD lt_result_output.

The lt_result_output table will contain something like:

total 240
lrwxr-xr-x   1 root   sys          8 Sep  2  2009 adm -> /var/adm
drwxr-xr-x   4 bin    bin      16384 Aug  1  2013 bin
dr-xr-xr-x   6 bin    bin         96 Jan 18  2009 ccs
dr-xr-xr-x   6 bin    bin         96 Jan 18  2009 conf
dr-xr-xr-x  16 bin    bin       8192 Aug  1  2013 contrib
dr-xr-xr-x   4 bin    bin         96 Jan 18  2009 dt
dr-xr-xr-x   3 bin    bin       8192 Apr 17  2013 etc
...

Note that lrwx... is for: l=link, d=directory, f=file, rwx=read, write, execute rights (3x).