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