浏览 6132 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-07-07
最后修改:2010-07-07
访问一个文件系统的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。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-07-09
呵呵,有什么不同点了
|
|
返回顶楼 | |
发表时间:2010-07-09
最后修改:2010-07-09
elvishehai 写道 呵呵,有什么不同点了
如果需要对这个FTPClient进行二次封装的话就可以看到不同点了。 比如客户需要接口 public interface FileAPI{ public InputStream getFile(String pathname); public OutputStream writeFile(String pathname); } 你没有办法同时把FTPClient也传给用户进行completePendingCommand |
|
返回顶楼 | |
发表时间:2010-08-09
同意的楼主的看法。
|
|
返回顶楼 | |
发表时间:2010-08-09
哦,应该继承FilterInputStream会更简单和直观
|
|
返回顶楼 | |
发表时间:2010-09-26
很好,终于解决了我困惑的问题
|
|
返回顶楼 | |