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).