#
第十章 使用FTP IRIS提供了一个类`%Net.FtpSession`,可以使用它从InterSystems IRIS内建立与FTP服务器的会话。 # 建立FTP会话 要建立FTP会话,请执行以下操作: 1. 创建`%Net.FtpSession`的实例。 2. 可以选择设置此实例的属性,以控制会话的常规行为: - `Timeout` 超时指定等待FTP服务器回复的时间(以秒为单位)。 - `SSLConfiguration`指定用于连接的激活的`SSL/TLS`配置(如果有)。如果`FTP`服务器使用HTTPS,请使用此选项。 - `TranslateTable`指定在读取文件内容或写入文件内容时要使用的转换表。 - `UsePASV`启用PASV模式。 - 当`FTP`服务器使用`https`时,`SSLCheckServerIdentity`适用。默认情况下,当`%Net.FtpSession`的实例连接到`SSL/TLS`服务器时,它会检查证书服务器名称是否与用于连接到服务器的DNS名称匹配。如果这些名称不匹配,则不允许连接。 若要禁用此检查,请将`SSLCheckServerIdentity`属性设置为0。 3. 调用`Connect()`方法以连接到特定的FTP服务器。 4. 调用`ascii()`或`binary()`方法将传输模式分别设置为ASCII模式或二进制模式。要查看当前传输模式,请检查实例的Type属性的值。 注意:`%Net.FtpSession`的每个方法都返回一个状态,应该检查该状态。这些方法还设置提供有关会话状态的有用信息的属性的值: - 如果当前已连接,则`CONNECTED`为TRUE,否则为FALSE。 - `ReturnCode`包含上次与FTP服务器通信时的返回代码。 - `ReturnMessage`包含上次与FTP服务器通信时的返回消息。 `Status()`方法返回(通过引用)FTP服务器的状态。 ## 命令的转换表 `%Net.FtpSession`在FTP服务器上查看文件名和路径名时,使用`RFC 2640`中介绍的技术自动处理字符集转换。当`%Net.FtpSession`的实例连接到FTP服务器时,它会使用Feat消息来确定服务器是否使用`UTF-8`字符。如果是,它将命令通道通信切换到`UTF-8`,以便所有文件名和路径名都可以正确地与`UTF-8`相互转换。 如果服务器不支持`FEAT`命令或未报告支持`UTF-8`,`%Net.FtpSession`实例将使用`RAW`模式并读取或写入RAW字节。 在极少数情况下,如果需要指定要使用的转换表,请设置`%Net.FtpSession`实例的`CommandTranslateTable`属性。一般情况下,应该没有必要使用此属性。 # FTP文件和系统方法 一旦建立了FTP会话,就可以调用会话实例的方法来执行FTP任务。`%Net.FtpSession`提供以下读写文件的方法: ### Delete() 删除文件。 ### Retrieve() 将文件从FTP服务器复制到InterSystems IRIS流中,并通过引用返回该流。要使用此流,请使用标准流方法:`Write()`、`WriteLine()`、`Read()`、`ReadLine()`、`Rewind()`、`MoveToEnd()`和`Clear()`。还可以使用流的`Size`属性。 ### RetryRetrieve() 允许继续检索文件,因为给定的流是由上一次使用`Retrieve()`创建的。 ### Store() 将 IRIS流的内容写入FTP服务器上的文件。 ### Append() 将流的内容追加到指定文件的末尾。 ### Rename() 重命名文件。 此外,`%Net.FtpSession`提供了导航和修改FTP服务器上的文件系统的方法:`GetDirectory()`、`SetDirectory()`、`SetToParentDirectory()`和`MakeDirectory()`。 要检查文件系统的内容,请使用`list()`或`NameList()`方法。 - `List()`创建一个流,其中包含其名称与给定模式匹配的所有文件的列表,并通过引用返回该流。 - `NameList()`创建文件名数组并通过引用返回该数组。 还可以使用`ChangeUser()`方法更改为其他用户;这比注销并再次登录要快。使用`Logout()`方法注销。 `System()`方法返回(通过引用)有关托管FTP服务器的计算机类型的信息。 `Size()`和`MDTM()`方法分别返回文件的大小和修改时间。 使用通用`sendCommand()`方法向FTP服务器发送命令并读取响应。此方法可用于发送`%Net.FtpSession`中未明确支持的命令。 # 使用链接的流上载大文件 如果要上传大文件,请考虑使用流接口的`LinkToFile()`方法。也就是说,不是创建流并将文件读入其中,而是创建流并将其链接到文件。在调用`%Net.FtpSession`的`Store()`方法时使用此链接流。 ```java Method SendLargeFile(ftp As %Net.FtpSession, dir As %String, filename As %String) { Set filestream=##class(%FileBinaryStream).%New() Set sc=filestream.LinkToFile(dir_filename) If $$$ISERR(sc) {do $System.Status.DisplayError(sc) quit } //上传的文件将与原始文件同名 Set newname=filename Set sc=ftp.Store(newname,filestream) If $$$ISERR(sc) {do $System.Status.DisplayError(sc) quit } } ``` # 自定义FTP服务器发出的回调 可以自定义`FTP`服务器生成的回调。例如,通过这样做,可以向用户提供服务器仍在处理大型传输的指示,或允许用户中止传输。 要自定义FTP回调,请执行以下操作: 1. 创建`%Net.FtpCallback`的子类。 2. 在这个子类中,实现`RetrieveCallback()`方法,该方法在从FTP服务器接收数据时定期调用。 3. 还要实现`StoreCallback()`方法,在将数据写入FTP服务器时会定期调用该方法。 4. 创建`FTP`会话时(如“建立FTP会话”中所述),将回调属性设置为等于的子类`%Net.FtpCallback`。