`
yangyi
  • 浏览: 112794 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

commons-net FTPClient API存取设计

    博客分类:
  • Java
阅读更多
文件系统无非就是文件的存取和组织结构。
访问一个文件系统的API也应该是写,读,定位方法(Pathname?/URI?)

FTPClient针对文件的保存和获取各提供了两个方法,分别是:
public boolean storeFile(String remote, InputStream local)
public OutputStream storeFileStream(String remote)

public boolean retrieveFile(String remote, OutputStream local)
public InputStream retrieveFileStream(String remote)


两个方法貌似相同,实际不同,返回流的那个因为不能马上处理流,所以需要用户手工调用completePendingCommand,而另一个传递流进去的则不需要。可能有同学已经遇到过这个问题了,读写第一个文件时总是正确的,当相同API读写第二个文件时,block住了。这是因为FTPClient要求在进行流操作之后执行completePendingCommand,以确保流处理完毕,因为流处理不是即时的,所以也没有办法不手工调用completePendingCommand。问题是开发者把不返回流的方法末尾加上了completePendingCommand,如果不看代码可能根本不知道。
文档上说:
引用
     * There are a few FTPClient methods that do not complete the
     * entire sequence of FTP commands to complete a transaction.  These
     * commands require some action by the programmer after the reception
     * of a positive intermediate command.  After the programmer's code
     * completes its actions, it must call this method to receive
     * the completion reply from the server and verify the success of the
     * entire transaction.

但是这样仍然还是让人有点困惑,为什么都是存储/读取的方法,有时候要调用completePendingCommand,有时候不调用?更严重的问题是completePendingCommand调用了getReply,如果一个命令通过socket stream传了过去但是没有getReply,即没有completePendingCommand,那么下次发命令时,将会受到本次返回码的干扰,得到无效的响应。而如果在completePendingCommand之后又进行了一次无辜的completePendingCommand,那么因为FTP Server上没有Reply了,就会block。所以completePendingCommand并不是可以随意添加的。

现在出现了两个问题:
1 completePendingCommand很容易多出来或遗漏
2 显式调用completePendingCommand暴露了底层实现,给用户带来不便,用户只想要InputStream或者OutputStream

为了解决这个问题,可以对InputStream进行扩展,建立一个ReplyOnCloseInputStream,如下:
private static ReplyOnCloseInputStream extends InputStream{
  //...
  public ReplyOnCloseInputStream(InputStream is, FTPClient c){
    //...
  }
  //...
  @override
  public void close(){
    if(c.completePendingCommand){
      is.close();
    }else{
      //throw Exception
    }
  }
} 
//...
return new ReplyOnCloseInputStream(is, client);

这样封装之后,FTPClient的用户只需要正常在处理完流之后关闭即可,而不必暴露实现细节。保存文件也可以用相同的方法封装OutputStream。
分享到:
评论
5 楼 smilerain 2010-09-26  
很好,终于解决了我困惑的问题
4 楼 yangyi 2010-08-09  
哦,应该继承FilterInputStream会更简单和直观
3 楼 zzbatluzhou 2010-08-09  
同意的楼主的看法。
2 楼 yangyi 2010-07-09  
elvishehai 写道
呵呵,有什么不同点了

如果需要对这个FTPClient进行二次封装的话就可以看到不同点了。
比如客户需要接口
public interface FileAPI{
  public InputStream getFile(String pathname);
  public OutputStream writeFile(String pathname);
}

你没有办法同时把FTPClient也传给用户进行completePendingCommand
1 楼 elvishehai 2010-07-09  
呵呵,有什么不同点了

相关推荐

    commons-net-3.8.0-API文档-中文版.zip

    包含翻译后的API文档:commons-net-3.8.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-net:commons-net:3.8.0; 标签:commons、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开...

    commons-net-3.3-API文档-中文版.zip

    包含翻译后的API文档:commons-net-3.3-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-net:commons-net:3.3; 标签:commons、net、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开...

    commons-net-3.6-API文档-中英对照版.zip

    包含翻译后的API文档:commons-net-3.6-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:commons-net:commons-net:3.6; 标签:commons、net、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档...

    commons-net-3.1-API文档-中英对照版.zip

    包含翻译后的API文档:commons-net-3.1-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven信息:groupId:commons-net,artifactId:commons-net,version:3.1 使用方法:解压翻译后的API文档,用浏览器打开...

    commons-net-2.2-API文档-中文版.zip

    包含翻译后的API文档:commons-net-2.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-net:commons-net:2.2; 标签:commons、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开...

    commons-lang3-3.12.0-API文档-中文版.zip

    包含翻译后的API文档:commons-lang3-3.12.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.commons:commons-lang3:3.12.0; 标签:apache、lang3、commons、jar包、java、中文文档; 使用方法:解压...

    commons-io-1.3.2-API文档-中文版.zip

    包含翻译后的API文档:commons-io-1.3.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-io:commons-io:1.3.2; 标签:commons、io、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开...

    commons-net-3.1-API文档-中文版.zip

    包含翻译后的API文档:commons-net-3.1-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:commons-net,artifactId:commons-net,version:3.1 使用方法:解压翻译后的API文档,用浏览器打开“index....

    commons-net-3.8.0-API文档-中英对照版.zip

    包含翻译后的API文档:commons-net-3.8.0-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:commons-net:commons-net:3.8.0; 标签:commons、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档...

    commons-lang3-3.9-API文档-中文版.zip

    包含翻译后的API文档:commons-lang3-3.9-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.commons:commons-lang3:3.9; 标签:apache、commons、lang3、中文文档、jar包、java; 使用方法:解压翻译后的...

    commons-math3-3.5-API文档-中文版.zip

    包含翻译后的API文档:commons-math3-3.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.commons:commons-math3:3.5; 标签:apache、commons、math3、中文文档、jar包、java; 使用方法:解压翻译后的...

    commons-exec-1.3-API文档-中文版.zip

    包含翻译后的API文档:commons-exec-1.3-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.commons:commons-exec:1.3; 标签:apache、commons、exec、中文文档、jar包、java; 使用方法:解压翻译后的API...

    commons-io-2.11.0-API文档-中文版.zip

    包含翻译后的API文档:commons-io-2.11.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-io:commons-io:2.11.0; 标签:commons、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开...

    commons-net-3.3-API文档-中英对照版.zip

    包含翻译后的API文档:commons-net-3.3-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:commons-net:commons-net:3.3; 标签:commons、net、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档...

    commons-math3-3.6.1-API文档-中英对照版.zip

    包含翻译后的API文档:commons-math3-3.6.1-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.apache.commons:commons-math3:3.6.1; 标签:apache、math3、commons、jar包、java、中英对照文档; 使用...

    commons-codec-1.15-API文档-中英对照版.zip

    包含翻译后的API文档:commons-codec-1.15-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:commons-codec:commons-codec:1.15; 标签:codec、commons、jar包、java、中英对照文档; 使用方法:解压翻译...

    commons-compress-1.21-API文档-中文版.zip

    包含翻译后的API文档:commons-compress-1.21-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.commons:commons-compress:1.21; 标签:apache、commons、compress、中文文档、jar包、java; 使用方法:...

    commons-io-2.5-API文档-中文版.zip

    包含翻译后的API文档:commons-io-2.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-io:commons-io:2.5; 标签:commons、io、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开...

    commons-lang3-3.7-API文档-中文版.zip

    包含翻译后的API文档:commons-lang3-3.7-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.commons:commons-lang3:3.7; 标签:apache、lang3、commons、jar包、java、中文文档; 使用方法:解压翻译后的...

    commons-dbutils-1.7-API文档-中文版.zip

    包含翻译后的API文档:commons-dbutils-1.7-javadoc-API文档-中文(简体)版.zip; Maven坐标:commons-dbutils:commons-dbutils:1.7; 标签:commons、dbutils、中文文档、jar包、java; 使用方法:解压翻译后的API...

Global site tag (gtag.js) - Google Analytics