狂奔 lion

          自強不息

          commons-net FTPClient API存取設計

          文件系統無非就是文件的存取和組織結構。
          訪問一個文件系統的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。



           @2008 楊一. 版權所有. 保留所有權利

          posted on 2010-07-07 23:08 楊一 閱讀(3469) 評論(1)  編輯  收藏 所屬分類: Java SE

          評論

          # re: commons-net FTPClient API存取設計 2010-07-08 09:38 Princeton

          private static ReplyOnCloseInputStream extends InputStream{

          上面這行代碼有點搞不懂!  回復  更多評論   

          <2010年7月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導航

          公告

          本人在blogjava上發表的文章及隨筆除特別聲明外均為原創或翻譯,作品受知識產權法保護并被授權遵從 知識分享協議:署名-非商業性使用-相同方式共享 歡迎轉載,請在轉載時注明作者姓名(楊一)及出處(www.aygfsteel.com/yangyi)
          /////////////////////////////////////////
          我的訪問者

          常用鏈接

          留言簿(5)

          隨筆分類(55)

          隨筆檔案(55)

          相冊

          Java

          其他技術

          生活

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          自強不息


          用心 - 珍惜時間,勇于創造
          主站蜘蛛池模板: 隆化县| 民和| 友谊县| 延边| 格尔木市| 定结县| 屏山县| 望都县| 阳高县| 黄大仙区| 闽清县| 江都市| 肥东县| 新平| 天祝| 台山市| 巴彦县| 普兰店市| 四子王旗| 交城县| 福泉市| 玉山县| 阿图什市| 巫山县| 河津市| 德钦县| 襄汾县| 永泰县| 绵阳市| 扎鲁特旗| 大竹县| 沙湾县| 曲周县| 林甸县| 通化县| 阿巴嘎旗| 乌兰察布市| 牡丹江市| 襄垣县| 武城县| 辽阳市|