原文地址如下,笔者有删改。
近来,在ABAP论坛上,从ABAP使用FTP似乎成了一个热门话题。
我想坐下来整理一下我能找到的关于这个话题的所有信息,并以博客的形式分享出来。
多年来,我见证了许多不同的解决方案,用于在SAP系统上上传输文件。我见过用操作系统的脚本语言编写的外部FTP脚本。我也见过全功能的自定义应用程序,它们是为与SAP系统接口而设计的。然而,我认为你会发现,执行一个简单的从ABAP进行FTP的大部分技术需求已经包含在标准系统中。我的所有例子和截图都将来自于一个46C系统。
SAP的解决方案
如果你曾经查看过你的SAP系统的内核目录,你可能会注意到一个有趣的小可执行文件:sapftp.exe
(Windows SAP内核上的文件名)。正是这部分内核向ABAP编程语言公开了FTP功能。
所以,你怀疑ABAP中有FTP功能,但你不太确定如何使用它。你应该从哪里开始呢?我总是首先转向 SAP Service Market place
.
在SAPFTP上快速搜索显示,有一个完整的组件(BC-SRV-COM-FTP
)专门讨论这个话题。
最常见的说明和我们的起点是OSS Note 93042。这个说明首先提供了一个关于SAPFTP是什么的好描述:一个通过RFC从ABAP访问的客户端RFC应用程序。但我们也发现,除了SAPFTP是内核的一部分之外,它也是SAPGui的一部分
。这意味着我们可以从我们的R/3服务器或从客户端工作站执行FTP命令。
如果这个解决方案是通过RFC访问的,那么我们必须设置一些RFC目的地。事实上,我们需要两个;一个是前端FTP的SAPFTP,另一个是应用服务器上访问的SAPFTPA。幸运的是,我们甚至不需要在SM59中设置这些RFC目的地。SAP已经提供了一个程序RSFTP005
,为我们生成这些目的地。
在我们开始自己编写代码访问这些FTP功能之前,我们为什么不确保一切都已设置并且运行正常。SAP再次通过提供一个测试程序RSFTP002
帮助我们。(如果你好奇,FTP功能和许多其他测试程序都包含在SAP开发类SFTP中。)当我们运行这个测试时,我们会得到一些输入参数,比如服务器、用户名密码等。我们想从简单的开始,只是确保我们能够连接。因此,我们将只执行pwd命令(打印工作目录)。
你的答案应该是这样的:
如果你想看看FTP命令的列表,试着使用HELP命令替代PWD:
如果在测试中出了问题,我建议你在SM59中为FTP目的地激活跟踪选项。然后你可以使用程序RSFTP001来显示当前的跟踪文件。
编程FTP
不仅RSFTP002程序为我们提供了一个测试环境,它还为我们提供了一个编程示例。我们可以看到,FTP功能实际上是由SFTP功能组内的一组功能模块提供的。
我们有基本的命令,如FTP_CONNECT, FTP_COMMAND和FTP_DISCONNECT,这些命令可以连续使用,以完成完整的文件操作动作。
FTP_COMMAND功能模块允许你发出任意FTP命令,只要SAPFTP功能、主机和目的服务器都支持该命令。然后你有专门的功能,如FTP_R3_TO_SERVER, FTP_R3_TO_CLIENT和FTP_CLIENT_TO_R3。这使你可以将一些数据在内存中移动到其他地方。
这样做的好处是不必先将数据写入文件系统,也不必发出任何FTP命令。然而,这些功能也仅限于所描述的范围。
如果你已经熟悉FTP的基本操作,使用这些功能模块应该不会觉得太难。Connect、Command、Disconnect动作应该是不言自明的。
所以我们不必详细查看整个程序,而是专注于两个可能不熟悉的事物。首先,程序以一个ABAP内核系统调用AB_RFC_X_SCRAMBLE_STRING开始。
好吧,我们不想公开传递一个可能敏感的密码。因此,FTP_CONNECT功能模块要求在接收密码前对其进行加密。正是这个系统调用执行了这种单向加密。现在我查了一个620 SP42系统,在这个示例中,SAP用HTTP_SCRAMBLE函数调用替换了AB_RFC_X_SCRAMBLE_STRING。不幸的是,HTTP_SCRAMBLE在我的46C系统中甚至不存在。关于这些功能调用的另一件我想指出的事情是FTP_CONNECT的输出参数。它传回一个叫做handle的参数。这个句柄随后成为所有后续调用的输入参数:FTP_COMMAND和FTP_CLOSE。这个句柄是我们用FTP_CONNECT开始的FTP实例的指针。这确保我们在每个命令中重新连接到同一个FTP会话。
FTP开发
我想分享一些可以使用这个FTP功能构建的事物。首先,我不希望有一堆ABAP程序直接使用SAP FTP功能模块。如你所见,密码加密示例在46C和620之间已经有所不同。因此,我认为最好将所有FTP功能封装在一个自定义ABAP OO类中。这不仅让我有机会隐藏内部SAP功能并在升级期间轻松切换,而且还能保持一致的错误处理。我在类的构造函数中接受用户名、密码、主机和RFC目的地。然后我将这些值存储在受保护的属性中。每个功能模块都作为一个实例方法实现。密码加密功能也都巧妙地隐藏在类中。此外,调用程序也不必担心跟踪FTP句柄,因为它是一个实例属性。
我想要一种记录整个FTP脚本的方法,这些脚本可以在运行时填充值,并作为后台作业的一个步骤运行。我的公司过去有许多接口频繁运行,发送文件到各处。我们需要一种机制来监视和支持这些文件移动。这确实是这个工具的根本,但它也让你看到这些功能可以有多强大。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。