Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Scan a directory on application server with LONG file names

Former Member
0 Kudos

Hi all,

I need to get the list of all files on a directory on the application server, but I can't find any satisfying method, because the directory name may be long and the filenames too.

- Function modules RZL_READ_DIR and RZL_READ_DIR_LOCAL : the output table contains file names up to 32 CHAR only

- Function module EPS_GET_DIRECTORY_LISTING : the directory name is 60 CHAR only, and the output table contains file names up to 40 CHAR only

- Following instruction is perfect, but is reserved for internal use only :

CONCATENATE 'ls' w_directory INTO w_unixcommand  SEPARATED BY space.
CALL 'SYSTEM' ID 'COMMAND' FIELD w_unixcommand
              ID 'TAB'     FIELD wt_files[].

SAP recommend to replace CALL instructions with methods from classes, but I can't find any.

Please do you have any solution ?

Thanks in advance.

24 REPLIES 24

Former Member
0 Kudos

Hi,

I have a same sort of problem a long back, shring the sample code with you...

TYPES : t_name_of_dir(1024)        TYPE c,
        t_name_of_file(260)        TYPE c.
TYPES : BEGIN OF t_file_lst,
        dirname     TYPE t_name_of_dir," name of directory. (possibly
                                       " truncated.)
        name        TYPE t_name_of_file, " name of entry. (possibly
                                       " truncated.)
        type(10)    TYPE c,            " type of entry.
        len(8)      TYPE p,            " length in bytes.
        owner(8)    TYPE c,            " owner of the entry.
        mtime(6)    TYPE p, " last modification date, seconds since 1970
        mode(9)     TYPE c, " like "rwx-r-x--x": protection mode.
        useable(1)  TYPE c,
        subrc(4)    TYPE c,
        errno(3)    TYPE c,
        errmsg(40)  TYPE c,
        mod_date    TYPE d,
        mod_time(8) TYPE c,            " hh:mm:ss
        seen(1)     TYPE c,
        changed(1)  TYPE c,
        END OF t_file_lst.

DATA: i_file_list TYPE TABLE OF t_file_lst WITH HEADER LINE.

  w_dir_name = p_path.
*D30K966224if
  CALL 'C_DIR_READ_FINISH'             " just to be sure
      ID 'ERRNO'  FIELD i_file_list-errno
      ID 'ERRMSG' FIELD i_file_list-errmsg.

  CALL 'C_DIR_READ_START' ID 'DIR'    FIELD w_dir_name
                          ID 'FILE'   FIELD w_generic_name
                          ID 'ERRNO'  FIELD s_file_lst-errno
                          ID 'ERRMSG' FIELD s_file_lst-errmsg.
  IF sy-subrc <> 0.
    sy-subrc = 4.
    EXIT.
  ENDIF.

  DO.
    CLEAR s_file_lst.
    CALL 'C_DIR_READ_NEXT'
      ID 'TYPE'   FIELD s_file_lst-type
      ID 'NAME'   FIELD s_file_lst-name
      ID 'LEN'    FIELD s_file_lst-len
      ID 'OWNER'  FIELD s_file_lst-owner
      ID 'MTIME'  FIELD s_file_lst-mtime
      ID 'MODE'   FIELD s_file_lst-mode
      ID 'ERRNO'  FIELD s_file_lst-errno
      ID 'ERRMSG' FIELD s_file_lst-errmsg.
    s_file_lst-dirname = w_dir_name.
    MOVE sy-subrc TO s_file_lst-subrc.
    CASE sy-subrc.
      WHEN 0.
        CLEAR: s_file_lst-errno,
               s_file_lst-errmsg.
        CASE s_file_lst-type(1).
          WHEN 'F'.                 " normal file.
            PERFORM filename_useable USING s_file_lst-name
                                           s_file_lst-useable.
          WHEN 'f'.                 " normal file.
            PERFORM filename_useable USING s_file_lst-name
                                           s_file_lst-useable.
          WHEN OTHERS.              " directory, device, fifo, socket,...
            MOVE c_sap_no  TO s_file_lst-useable.
        ENDCASE.
        IF s_file_lst-len = 0.
          MOVE c_sap_no TO s_file_lst-useable.
        ENDIF.
      WHEN 1.                     " end of directory
        EXIT.
      WHEN 4.                     " filename too long
        MOVE c_sap_no TO s_file_lst-useable.
      WHEN OTHERS.
        IF sy-subrc = 5.
          MOVE: '???' TO s_file_lst-type,
                '???' TO s_file_lst-owner,
                '???' TO s_file_lst-mode.
        ENDIF.
        MOVE c_sap_no TO s_file_lst-useable.
    ENDCASE.
    PERFORM p6_to_date_time_tz(rstr0400) USING s_file_lst-mtime
                                               s_file_lst-mod_time
                                               s_file_lst-mod_date.
*   * Does the filename contains the requested pattern?
*   * Then store it, else forget it.
    IF w_pattern = c_no_cs.
      IF s_file_lst-useable NE c_sap_no.
        MOVE-CORRESPONDING s_file_lst TO i_file_list.
        APPEND i_file_list.
      ENDIF.
    ELSE.
      IF s_file_lst-name CS w_pattern.
        IF s_file_lst-useable NE c_sap_no.
          MOVE-CORRESPONDING s_file_lst TO i_file_list.
          APPEND i_file_list.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDDO.

  CALL 'C_DIR_READ_FINISH'
      ID 'ERRNO'  FIELD i_file_list-errno
      ID 'ERRMSG' FIELD i_file_list-errmsg.
  IF sy-subrc <> 0.
    WRITE: / 'C_DIR_READ_FINISH', 'SUBRC', sy-subrc.
  ENDIF.
  SORT i_file_list BY mod_date ASCENDING. "herer is the list of all the files 

*&---------------------------------------------------------------------*
*&      Form  filename_useable
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_S_FILE_NAME  text
*      -->P_S_FILE_USEABLE  text
*----------------------------------------------------------------------*
FORM filename_useable USING a_name a_useable.

  DATA w_name(75).

  w_name = a_name.
  IF w_name(4) = 'core'.
    a_useable = c_sap_no.
  ELSE.
    a_useable = c_sap_yes.
  ENDIF.
ENDFORM.

Edited by: Lokesh Tarey on Jan 17, 2012 2:47 PM

bryan_cain
Contributor
0 Kudos

You could also create an OS command in SM69 that basically does a



ls > file.txt

And then parse the contents of file.txt

0 Kudos
    • sorry wrong thread*** taking out old comment.

-


ok for this thead..

you dont have to have authorization for SM69.. there is a predefined command as ls... you just have to use it..

Former Member
0 Kudos

@ Lokesh : thanks but your code template contains instructions "CALL" and I don't want to use them because of SAP recommendations

@ Bryan : thanks but I have no authorization for using transaction SM69

0 Kudos

So ask your basis team for help? That's what they're there for, right? You won't need SM69 access once the command is created, you will use a FM like SXPG_COMMAND_EXECUTE to call the command, and then a typical "OPEN DATASET" to read the list.txt file.

0 Kudos

OK thanks Bryan.

I had a look to SM69 with an authorized user.

I have never used this transaction.

I can see there are 2 fields :

- Operating system command

- Parameters for operating system command

How should I exactly use these fields ?

How can I define the name of the scanned directory as a parameter ?

For the result file, should I replace in your example file.txt with something like /usr/sap/.../file.txt ?

0 Kudos

- Operating system command ls

- Parameters for operating system command nothing needed(to start with)

save, now execute, while executing it will ask additional parameter, here pass the directory you want to scan like

/usr/sap/tmp

and execute.

you will have output of ls command listed down.

0 Kudos

1. Go to SM69 and create a command name like below

Command name = ZLS
Operating system command = ls
Parameters for operating system command = ?

You need to save the command, press f3 and save again. Otherwise the command doesn't really save

2. You can now execute the command in SE37 using function SXPG_COMMAND_EXECUTE. Ensure the SAP OS user has access to the path which you want to list.

Upper/lower case = 'X'
COMMANDNAME = ZLS
ADDITIONAL_PARAMETERS = <full diretctory path where you want to list files>

or alternatively you can also test using SM49 transaction.

This means that the additional parameter above substitutes the ? place holder mentioned in step 1

The above will list files in directory path you specify.

0 Kudos

The test in SM69 is working --> good !

But when I try with FM SXPG_COMMAND_EXECUTE, I get a not-authorized exception because of authorization object S_LOG_COM.

So if any user who will execute my program has the same lack of authorisation, it is really a problem.

I am afraid this is not a convenient solution.

But thanks for your help anyway.

0 Kudos

i would rather say it IS a convenient solution. you should not read the data if you are not authorized to. whats wrong in it?

0 Kudos

I assume S_LOG_COM will allow you to specify only the commands you want? I understand not wanting to change security, but I agree with the above - they shouldn't see it if they don't have access to it. Plus, granting them access only to run that specific command is pretty low risk.

0 Kudos

Actually I have tested with a directory I am authorized to read.

I can access it through AL11 or with FM like RZL_READ_DIR_LOCAL... so I am authorized.

But the auth. object S_LOG_COM prevents me from executing the operating system command I have created.

0 Kudos

Theoretically you could wrap the FM to call the OS command in a program, then in your code create and execute a batch job for that program that runs under a different user ID.

But its probably easier just to update the security to allow people to run that command.

0 Kudos

yes.. as long as users dont control too much into what they are reading .. security/audit would also be fine with it.

Former Member
0 Kudos

Else, is there really no useful method from class ?

The equivalent of cl_gui_frontend_services=>directory_list_files for the application server ?

0 Kudos

/SAPDMC/LSM_F4_SERVER_FILE

check this FM.. just pass / or /usr and see the magic

so if you want that from your code then

perform DIRECTORY_CONTENTS_GET 
in program /SAPDMC/SAPLLSMW_AUX_020 TABLES   PT_FILE STRUCTURE GS_FILE
                            USING    P_DIRECTORY
                                     P_FILEMASK
                            CHANGING P_OK

0 Kudos

Great idea ! It works !

You rock, thanks a lot.

Former Member

You should use FM EPS2_GET_DIRECTORY_LISTING if available which uses eps2filnam / eps2fili with 200 characters.

0 Kudos

Awesome I was looking for one FM which could return file name with more than 100char, its the same.
Thanks a lot

0 Kudos

You're welcome!

0 Kudos

'EPS_GET_DIRECTORY_LISTING allows for directory name length of 60. This is a laugh.

Regards,

Clemens

0 Kudos

Hi, EPS2_GET_DIRECTORY_LISTING has the same problem than the one without the "2", it does an authority check over Transport organizer objects.

SUBST_GET_FILE_LIST is another common alternative which suffers from the same short length problem and additionally is wiped by SAP in recent releases.

To me is unbelievable that still SAP didn't provide a properly released general purpose f.m. without this limitations for this so common requirement.

Former Member
0 Kudos

Also, Long Path Tool can work good for such issues.

Erol_CAGLAR
Participant
0 Kudos

EPS2_GET_DIRECTORY_LISTING