文章目录
- 前言
- 一、连接FTP服务器
- 二、关于FTP命令
- 三、相关代码示例
- 1.连接FTP服务器
- 2.打开指定目录
- 3.查询该目录下所有文件,并获取文件名
- 4.解析相关文件
- 5.上传相关文件
- 6.剪切相关文件至其他目录
- 7.关闭连接
前言
关于SAP-FTP上操作说明网上可参考的内容略显单薄,特此种下树苗,为后来人好乘凉
一、连接FTP服务器
在敲代码前,先进行连接测试,确保FTP服务器与sap相通.
维护相关配置表 SM30->SAPFTP_SERVERS_V
FTP服务器IP,PORT 由FTP团队提供
例如:IP:144.144.144.144 端口号:21 描述 : SAPFTPA
SAP提供了标准的测试程序:SE38-> rsftp002
例如:
用户:user
密码:123456(密码最好小于9位数)
主机:144.144.144.144 21 (其中端口号意空格隔开)
命令:ls (ls命令是打开FTP目录列表)
RFC 目标系统:SAPFTPA (SAPTPA:以本地连接FTP服务器,SAPFTPA:以SAP服务器连接FTP服务器。项目中通常用SAPFTPA)
成功链接会返回相关的目录列表
失败则报错
二、关于FTP命令
FTP相关命令,可以查看相关FTP文档 或者 自行百度.
如:FTP大全详解
或者自行查阅相关资料,本文只介绍基础,常用命令
三、相关代码示例
1.连接FTP服务器
FORM ftpconnect USING es_ret TYPE zsappo_ret_info.
DATA:l_pwdlength TYPE i.
DATA:l_key TYPE i VALUE 26101957 .
DATA l_ftppwd(255) TYPE c.
SELECT SINGLE * FROM zwmt011 INTO @DATA(ls_zwmt011) .
IF sy-subrc NE 0.
es_ret-code = 'E'.
es_ret-msg = 'ZWMT011表数据未维护'.
RETURN.
ENDIF.
thosts = ls_zwmt011-ip. "'144.144.144.144 21'."
tusers = ls_zwmt011-zaccount."'USER'."P_USER.
tpword = ls_zwmt011-zpassword."'123456'."P_PWD.
l_pwdlength = strlen( tpword )."长度
* 定义RFC连接目标,前后台执行时不同
trfcdest = 'SAPFTPA'." 'SAPFTPA'.
*****************开始FTP传输数据**********
CALL FUNCTION 'HTTP_SCRAMBLE' "密码加密
EXPORTING
source = tpword
sourcelen = l_pwdlength
key = l_key
IMPORTING
destination = l_ftppwd.
*该函数可以定义有网关时账户密码,一般公司内部访问时无此设置
CALL FUNCTION 'FTP_CONNECT'
EXPORTING
user = tusers
password = l_ftppwd
host = thosts
rfc_destination = trfcdest
IMPORTING
handle = thandle"获取权柄
EXCEPTIONS
not_connected = 1
OTHERS = 2.
ENDFORM.
2.打开指定目录
命令:CD
FORM open_sel_path USING p_zpath.
DATA:BEGIN OF com OCCURS 0,
cmd(100) TYPE C,
END OF com.
DATA:BEGIN OF res OCCURS 0,
LINE(100) TYPE C,
END OF res.
CONCATENATE 'cd' p_zpath INTO com-cmd SEPARATED BY ' '."p_zpath为具体文件路径
CLEAR:RES[],y_subrc.
*执行FTP指令
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = thandle
command = com-cmd
TABLES
DATA = res
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
IF SY-SUBRC NE 0.
y_subrc = SY-subrc.
ENDIF.
ENDFORM.
3.查询该目录下所有文件,并获取文件名
此步骤需要先执行步骤2.后根据不同系统进行字段偏移来获取文件名
命令:dir
FORM read_filename_data USING del_zftp TYPE zftp_path.
DATA:BEGIN OF res OCCURS 0,
line(100) TYPE c,
END OF res.
CLEAR:gt_file.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = thandle
command = 'dir'
TABLES
data = res
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
LOOP AT res INTO DATA(s_res) WHERE line CS '.xml' OR line CS '.CONFIRM'OR line CS '.confirm' OR line CS '.XML'.
gs_file-filename = s_res-line+50.
APPEND gs_file TO gt_file.
CLEAR:gs_file.
ENDLOOP.
ENDFORM.
4.解析相关文件
CALL FUNCTION ‘FTP_SERVER_TO_R3’时需要注意character_mode 参数
如果 character_mode = ’ ’ 时,数据将以数据流的方式返回至 blob 表参数
character_mode = ’ X’ 时 时,数据将以文本的形式返回至text表参数
以下有两住方式提供参考
方式1:只解析单纯的文本
FORM deal_filename_data USING p_zftp TYPE zftp_path.
DATA:blob_length TYPE i.
DATA:filename TYPE rlgrap-filename .
DATA: BEGIN OF blob OCCURS 0,
line(100) TYPE x,
END OF blob.
DATA: BEGIN OF ls_line,
line(2000),
END OF ls_line,
lt_line LIKE TABLE OF ls_line.
DATA:lt_zwmt015 LIKE TABLE OF zwmt015,
ls_zwmt015 LIKE zwmt015.
CLEAR:lt_zwmt015.
LOOP AT gt_file INTO gs_file.
CLEAR:filename,blob_length,blob,lt_line.
filename = gs_file-filename.
CALL FUNCTION 'FTP_SERVER_TO_R3' "获取FTP服务器文件数据
EXPORTING
handle = thandle
fname = filename
character_mode = 'X' "参数为X此时文件会返回至TEXT
IMPORTING
blob_length = blob_length
TABLES
blob = blob
text = lt_line.
TRANSLATE gs_file-filename TO UPPER CASE.
SEARCH gs_file-filename FOR '.CONFIRM.DEL'.
IF sy-subrc = 0.
ls_zwmt015-zlot_number = gs_file-filename(sy-fdpos).
ls_zwmt015-ztype = p_zftp-ztype.
ls_zwmt015-zsource = p_zftp-zsource_fab.
ls_zwmt015-zdestination = p_zftp-zdestination_fab.
IF lt_line IS NOT INITIAL.
READ TABLE lt_line INTO ls_line INDEX 1.
IF sy-subrc = 0.
IF ls_line CS 'S'.
ls_zwmt015-type = 'S'.
ELSE.
ls_zwmt015-type = 'E'.
ENDIF.
ls_zwmt015-msg = ls_line-line.
ENDIF.
ELSE.
ls_zwmt015-type = 'E'.
ls_zwmt015-msg = '无法读取文件'&& filename.
ENDIF.
gs_lotid-lotid = ls_zwmt015-zlot_number.
APPEND gs_lotid TO gt_lotid.
CLEAR:gs_lotid.
APPEND ls_zwmt015 TO lt_zwmt015.
CLEAR:ls_zwmt015.
ENDIF.
CLEAR:gs_file.
ENDLOOP.
IF lt_zwmt015 IS NOT INITIAL.
MODIFY zwmt015 FROM TABLE lt_zwmt015.
IF sy-subrc = 0.
COMMIT WORK AND WAIT .
ELSE.
ROLLBACK WORK.
ENDIF.
ENDIF.
ENDFORM.
方式二:解析相关XML
FORM xml_filename_data USING p_zftp TYPE zftp_path.
DATA lt_xml TYPE xml_rawdata.
DATA:lv_xml TYPE xstring.
DATA:blob_length TYPE i.
DATA:filename TYPE rlgrap-filename .
DATA: BEGIN OF blob OCCURS 0,
line(100) TYPE x,
END OF blob.
DATA: BEGIN OF ls_line,
line(2000),
END OF ls_line,
lt_line LIKE TABLE OF ls_line.
DATA:lt_zwmt015 LIKE TABLE OF zwmt015,
ls_zwmt015 LIKE zwmt015.
CLEAR:lt_zwmt015.
LOOP AT gt_file INTO gs_file.
CLEAR:filename,blob_length,blob,lt_line.
filename = gs_file-filename.
CALL FUNCTION 'FTP_SERVER_TO_R3' "获取FTP服务器文件数据
EXPORTING
handle = thandle
fname = filename
character_mode = ' ' "参数为X此时文件会返回至blob
IMPORTING
blob_length = blob_length
TABLES
blob = blob
text = lt_line.
"转换成XSTRING格式
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length = blob_length
IMPORTING
buffer = lv_xml
TABLES
binary_tab = blob.
"解析XML转换成内表 相关配置要在TCODE :STRANS进行配置
CALL TRANSFORMATION zftp_xml
SOURCE XML lv_xml
RESULT lt_ftp = gt_ftp.
ENDLOOP.
ENDFORM.
5.上传相关文件
"前置条件 先执行步骤2打开指定路径
FORM update_ftp_file USING zlot_number es_ret TYPE zsappo_ret_info.
DATA:lv_xml TYPE xstring.
DATA:x_hash TYPE xstring.
DATA:lv_size TYPE i.
DATA lt_xml TYPE xml_rawdata.
DATA lt_hash TYPE xml_rawdata.
DATA:i_fname(100).
DATA LV_STR TYPE STRING.
DATA: lo_writer TYPE REF TO cl_sxml_string_writer.
lo_writer = cl_sxml_string_writer=>create(
type = if_sxml=>co_xt_xml10
encoding = `UTF-8` )."将抬头转换成UTF-8
CALL TRANSFORMATION zftp_xml
SOURCE lt_ftp = gt_ftp
*sflight = lt_itab2
RESULT XML lo_writer.
lv_xml = lo_writer->get_output( ).
i_fname = zlot_number && '.XML'.
PERFORM frm_ftr_server TABLES lt_xml USING lv_xml i_fname es_ret CHANGING lv_size.
IF es_ret-code = 'E'.
RETURN.
ENDIF.
"MD5加密校验文件完整性
CALL FUNCTION 'ZWMFU006'
EXPORTING
filelength = lv_size
IMPORTING
hash = e_hash
TABLES
binary_tab = lt_xml.
LV_STR = e_hash.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = LV_STR
* MIMETYPE = ' '
* ENCODING =
IMPORTING
buffer = x_hash
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
i_fname = zlot_number && '.CONFIRM'.
PERFORM frm_ftr_server TABLES lt_xml USING x_hash i_fname es_ret CHANGING lv_size.
IF es_ret-code = 'E'.
RETURN.
ENDIF.
ENDFORM.
FORM frm_ftr_server TABLES lt_raw TYPE xml_rawdata
USING x_str TYPE xstring
i_fname
es_ret TYPE zsappo_ret_info
CHANGING lv_size.
* DATA:lv_size TYPE i.
* DATA lt_raw TYPE xml_rawdata.
CLEAR:lt_raw.
CLEAR:lv_size.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = x_str
IMPORTING
output_length = lv_size
TABLES
binary_tab = lt_raw.
* i_fname = zlot_number && '.xml'.
CALL FUNCTION 'FTP_R3_TO_SERVER'
EXPORTING
handle = thandle
fname = i_fname "'ZPPT035-ZDESNATION LOT_NUMBER.XML' "l_filename
blob_length = lv_size
character_mode = ' '
TABLES
blob = lt_raw
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
IF sy-subrc NE 0.
es_ret-code = 'E'.
es_ret-msg = i_fname && '文件上传失败'.
ENDIF.
ENDFORM.
6.剪切相关文件至其他目录
命令:rename 此命令也可用于重命名
FORM frm_copy_file USING p_zftp TYPE zftp_path
w_zftp TYPE zftp_path
del_zftp TYPE zftp_path.
DATA:p_zpath TYPE zftp_path-zpath.
DATA:w_zpath TYPE zftp_path-zpath.
DATA:del_zpath TYPE zftp_path-zpath.
"打开指定目录
PERFORM open_sel_path USING p_zftp-zpath.
"剪切
LOOP AT gt_lotid INTO gs_lotid.
".XML
p_zpath = p_zftp-zpath && '/' && gs_lotid-lotid && '.xml'.
w_zpath = w_zftp-zpath && '/' && gs_lotid-lotid && '.xml'.
PERFORM frm_move_file USING p_zpath w_zpath.
"confirm
p_zpath = p_zftp-zpath && '/' && gs_lotid-lotid && '.confirm'.
w_zpath = w_zftp-zpath && '/' && gs_lotid-lotid && '.confirm'.
PERFORM frm_move_file USING p_zpath w_zpath.
CLEAR:gs_lotid.
ENDLOOP.
ENDFORM.
FORM open_sel_path USING p_zpath.
DATA:BEGIN OF com OCCURS 0,
cmd(100) TYPE C,
END OF com.
DATA:BEGIN OF res OCCURS 0,
LINE(100) TYPE C,
END OF res.
CONCATENATE 'cd' p_zpath INTO com-cmd SEPARATED BY ' '.
CLEAR:RES[],y_subrc.
*执行FTP指令
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = thandle
command = com-cmd
TABLES
DATA = res
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
IF SY-SUBRC NE 0.
y_subrc = SY-subrc.
ENDIF.
ENDFORM.
FORM frm_move_file USING p_zpath"源
w_zpath."目的地
DATA:BEGIN OF com OCCURS 0,
cmd(500) TYPE c,
END OF com.
DATA:BEGIN OF res OCCURS 0,
line(100) TYPE c,
END OF res.
CONCATENATE 'rename' p_zpath w_zpath INTO com-cmd SEPARATED BY space.
CALL FUNCTION 'FTP_COMMAND'
EXPORTING
handle = thandle
command = com-cmd
TABLES
data = res
EXCEPTIONS
tcpip_error = 1
command_error = 2
data_error = 3
OTHERS = 4.
ENDFORM.
7.关闭连接
"关闭FTP 连接
CALL FUNCTION 'FTP_DISCONNECT'
EXPORTING
handle = thandle.