java ftp api_commons-net FTPClient API存取设计

文件系统无非就是文件的存取和组织结构。

访问一个文件系统的API也应该是写,读,定位方法(Pathname?/URI?)

FTPClient针对文件的保存和获取各提供了两个方法,分别是:

4f1150b881333f12a311ae9ef34da474.pngpublicbooleanstoreFile(String remote, InputStream local)

4f1150b881333f12a311ae9ef34da474.pngpublicOutputStream storeFileStream(String remote)

4f1150b881333f12a311ae9ef34da474.png

4f1150b881333f12a311ae9ef34da474.pngpublicbooleanretrieveFile(String remote, OutputStream local)

4f1150b881333f12a311ae9ef34da474.pngpublicInputStream retrieveFileStream(String remote)

4f1150b881333f12a311ae9ef34da474.png

两个方法貌似相同,实际不同,返回流的那个因为不能马上处理流,所以需要用户手工调用completePendingCommand,而另一个传递流进去的则不需要。可能有同学已经遇到过这个问题了,读写第一个文件时总是正确的,当相同API读写第二个文件时,block住了。这是因为FTPClient要求在进行流操作之后执行completePendingCommand,以确保流处理完毕,因为流处理不是即时的,所以也没有办法不手工调用completePendingCommand。问题是开发者把不返回流的方法末尾加上了completePendingCommand,如果不看代码可能根本不知道。

文档上说:

4f1150b881333f12a311ae9ef34da474.png*There are a few FTPClient methods thatdonot complete the

4f1150b881333f12a311ae9ef34da474.png*entire sequence of FTP commands to complete a transaction.  These

4f1150b881333f12a311ae9ef34da474.png*commands require some action by the programmer after the reception

4f1150b881333f12a311ae9ef34da474.png*of a positive intermediate command.  After the programmer's code4f1150b881333f12a311ae9ef34da474.png*completes its actions, it must callthismethod to receive

4f1150b881333f12a311ae9ef34da474.png*the completion reply from the server and verify the success of the

4f1150b881333f12a311ae9ef34da474.png*entire transaction.

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

现在出现了两个问题:

1 completePendingCommand很容易多出来或遗漏

2 显式调用completePendingCommand暴露了底层实现,给用户带来不便,用户只想要InputStream或者OutputStream

为了解决这个问题,可以对InputStream进行扩展,建立一个ReplyOnCloseInputStream,如下:

1fa987a29c6482f53d401256f96355eb.png

ca75c07623e1b494fee67e8f316fc310.gifprivatestaticReplyOnCloseInputStreamextendsInputStream9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png//9b8a8a44dd1c74ae49c20a7cd451974e.png97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicReplyOnCloseInputStream(InputStream is, FTPClient c)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png//9b8a8a44dd1c74ae49c20a7cd451974e.pngecedf933ec37d714bd4c2545da43add2.png}d18c02628675d0a2c816449d98bda930.png//9b8a8a44dd1c74ae49c20a7cd451974e.pngd18c02628675d0a2c816449d98bda930.png@override

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifpublicvoidclose()9b8a8a44dd1c74ae49c20a7cd451974e.png{

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gifif(c.completePendingCommand)9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png      is.close();

97e794c86028c5f5b5461ae5ef440a4c.png

3c6cafce68eb941a00f1998f1d3d3aa6.gif    }else9b8a8a44dd1c74ae49c20a7cd451974e.png{

d18c02628675d0a2c816449d98bda930.png//throw Exceptionecedf933ec37d714bd4c2545da43add2.png}ecedf933ec37d714bd4c2545da43add2.png  }8f1ba5b45633e9678d1db480c16cae3f.png}4f1150b881333f12a311ae9ef34da474.png//9b8a8a44dd1c74ae49c20a7cd451974e.png4f1150b881333f12a311ae9ef34da474.pngreturnnewReplyOnCloseInputStream(is, client);

这样封装之后,FTPClient的用户只需要正常在处理完流之后关闭即可,而不必暴露实现细节。保存文件也可以用相同的方法封装OutputStream。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值