posts - 310, comments - 6939, trackbacks - 0, articles - 3
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          用Java實現(xiàn)FTP批量大文件上傳下載(二)

          Posted on 2007-10-22 09:43 詩特林 閱讀(11579) 評論(15)  編輯  收藏 所屬分類: Socket
                                                  用Java實現(xiàn)FTP批量大文件上傳下載(二) 

        1. 用Java實現(xiàn)FTP批量大文件上傳下載(六)--代碼及示例下載
        2. 用Java實現(xiàn)FTP批量大文件上傳下載(五) --運行效果圖
        3. 用Java實現(xiàn)FTP批量大文件上傳下載(四)
        4. 用Java實現(xiàn)FTP批量大文件上傳下載(三)
        5. 用Java實現(xiàn)FTP批量大文件上傳下載(二)
        6. 用Java實現(xiàn)FTP批量大文件上傳下載(一)
           
        7. 2 上傳下載

          文件的上傳可以分成多線程及單線程,在單線程情況下比較簡單,而在多線程的情況下,要處理的事情要多點,同時也要小心很多。下面是net.sf.jftp.net.FtpConnection的上傳handleUpload方法。已經(jīng)考慮了單線程及多線程兩種不同的類型。

          public int handleUpload(String file, String realName)
              
          {
                  
          if(Settings.getEnableMultiThreading() &&
                         (
          !Settings.getNoUploadMultiThreading()))
                  
          {
                      Log.out(
          "spawning new thread for this upload.");

                      FtpTransfer t;

                      
          if(realName != null)
                      
          {
                          t 
          = new FtpTransfer(host, port, getLocalPath(), getCachedPWD(),
                                              file, username, password, Transfer.UPLOAD,
                                              handler, listeners, realName, crlf);
                      }

                      
          else
                      
          {
                          t 
          = new FtpTransfer(host, port, getLocalPath(), getCachedPWD(),
                                              file, username, password, Transfer.UPLOAD,
                                              handler, listeners, crlf);
                      }


                      lastTransfer 
          = t;

                      
          return NEW_TRANSFER_SPAWNED;
                  }

                  
          else
                  
          {
                      
          if(Settings.getNoUploadMultiThreading())
                      
          {
                          Log.out(
          "upload multithreading is disabled.");
                      }

                      
          else
                      
          {
                          Log.out(
          "multithreading is completely disabled.");
                      }


                      
          return (realName == null? upload(file) : upload(file, realName);
                  }

          }


           

          在多線程的情況下,有一個單獨的類net.sf.jftp.net .FtpTransfer,當然,多線程情況下,此類肯定是一個單獨的線程了。與JConnection相似,其線程的啟動也是在構造方法中啟動。而在它的run方法中,進行文件的讀取及傳輸。

          public void run()
              
          {
                  
          if(handler.getConnections().get(file) == null)
                  
          {
                      handler.addConnection(file, 
          this);
                  }

                  
          else if(!pause)
                  
          {
                      Log.debug(
          "Transfer already in progress: " + file);
                      work 
          = false;
                      stat 
          = 2;

                      
          return;
                  }


                  
          boolean hasPaused = false;

                  
          while(pause)
                  
          {
                      
          try
                      
          {
                          runner.sleep(
          100);

                          
          if(listeners != null)
                          
          {
                              
          for(int i = 0; i < listeners.size(); i++)
                              
          {
                                  ((ConnectionListener) listeners.elementAt(i)).updateProgress(file,
                                                                                               PAUSED,
                                                                                               
          -1);
                              }

                          }


                          
          if(!work)
                          
          {
                              
          if(listeners != null)
                              
          {
                                  
          for(int i = 0; i < listeners.size(); i++)
                                  
          {
                                      ((ConnectionListener) listeners.elementAt(i)).updateProgress(file,
                                                                                                   REMOVED,
                                                                                                   
          -1);
                                  }

                              }

                          }

                      }

                      
          catch(Exception ex)
                      
          {
                      }


                      hasPaused 
          = true;
                  }


                  
          while((handler.getConnectionSize() >= Settings.getMaxConnections()) &&
                            (handler.getConnectionSize() 
          > 0&& work)
                  
          {
                      
          try
                      
          {
                          stat 
          = 4;
                          runner.sleep(
          400);

                          
          if(!hasPaused && (listeners != null))
                          
          {
                              
          for(int i = 0; i < listeners.size(); i++)
                              
          {
                                  ((ConnectionListener) listeners.elementAt(i)).updateProgress(file,
                                                                                               QUEUED,
                                                                                               
          -1);
                              }

                          }

                          
          else
                          
          {
                              
          break;
                          }

                      }

                      
          catch(Exception ex)
                      
          {
                          ex.printStackTrace();
                      }

                  }


                  
          if(!work)
                  
          {
                      
          if(listeners != null)
                      
          {
                          
          for(int i = 0; i < listeners.size(); i++)
                          
          {
                              ((ConnectionListener) listeners.elementAt(i)).updateProgress(file,
                                                                                           REMOVED,
                                                                                           
          -1);
                          }

                      }


                      handler.removeConnection(file);
                      stat 
          = 3;

                      
          return;
                  }


                  started 
          = true;

                  
          try
                  
          {
                      runner.sleep(Settings.ftpTransferThreadPause);
                  }

                  
          catch(Exception ex)
                  
          {
                  }


                  con 
          = new FtpConnection(host, port, remotePath, crlf);

                  con.setConnectionHandler(handler);
                  con.setConnectionListeners(listeners);

                  
          int status = con.login(user, pass);

                  
          if(status == FtpConnection.LOGIN_OK)
                  
          {
                      File f 
          = new File(localPath);
                      con.setLocalPath(f.getAbsolutePath());

                      
          if(type.equals(UPLOAD))
                      
          {
                          
          if(newName != null)
                          
          {
                              transferStatus 
          = con.upload(file, newName);
                          }

                          
          else
                          
          {
                              transferStatus 
          = con.upload(file);
                          }

                      }

                      
          else
                      
          {
                          transferStatus 
          = con.download(file,this.newName);
                      }

                  }


                  
          if(!pause)
                  
          {
                      handler.removeConnection(file);
                  }

              }



           

          至于下載的過程,因為它是上傳的逆過程,與上傳的方法及寫法大同小異,在些出于篇幅的考慮,并沒有將代碼列出,但其思想及思路完全一樣。請讀者參考源代碼。

           

          、  進度條

           

          可以想象,如果在上傳或是下載的過程中,沒有任何的提示,用戶根本沒法判斷任務是否完成或是任務是否死了,常常由于上傳時間或下載時間過長而誤導用戶。因此,進度條就顯得非常的重要與實用。

          進度條的實現(xiàn),其實說起來很簡單。就是在程序中開啟兩個線程,第一個線程用于動態(tài)的改變界面上進度條的value值,而第二個線程則在上傳或是下載的過程中,做成一個循環(huán),在此循環(huán)中,每次讀取一定數(shù)量如8192字節(jié)數(shù)的數(shù)據(jù)。然后傳完此數(shù)據(jù)后,調(diào)用第一個線程中的updateProgress方法,來更新界面進度條的value值。

          而上傳或下載的過程中(見上一節(jié)的FtpTransfer類的run方法),可以查看,con.upload(file, newName)方法,代碼如下所示,

              public int upload(String file, String realName, InputStream in)
              
          {
                  hasUploaded 
          = true;
                  Log.out(
          "ftp upload started: " + this);

                  
          int stat;

                  
          if((in == null&& new File(file).isDirectory())
                  
          {
                      shortProgress 
          = true;
                      fileCount 
          = 0;
                      baseFile 
          = file;
                      dataType 
          = DataConnection.PUTDIR;
                      isDirUpload 
          = true;

                      stat 
          = uploadDir(file);

                      shortProgress 
          = false;

                      
          //System.out.println(fileCount + ":" + baseFile);
                      fireProgressUpdate(baseFile,
                                         DataConnection.DFINISHED 
          + ":" + fileCount, -1);

                      fireActionFinished(
          this);
                      fireDirectoryUpdate(
          this);
                  }

                  
          else
                  
          {
                      dataType 
          = DataConnection.PUT;
                      stat 
          = rawUpload(file, realName, in);

                      
          try
                      
          {
                          Thread.sleep(
          100);
                      }

                      
          catch(Exception ex)
                      
          {
                      }


                      fireActionFinished(
          this);
                      fireDirectoryUpdate(
          this);
                  }


                  
          try
                  
          {
                      Thread.sleep(
          500);
                  }

                  
          catch(Exception ex)
                  
          {
                  }


                  
          return stat;
              }


           

          此方法進行負責上傳一定字節(jié)數(shù)量的內(nèi)容,其實就是調(diào)用rawUpload方法,這里沒列出,請參考源代碼,而當傳完此字節(jié)數(shù)據(jù)后,通過調(diào)用fireActionFinished()方法來調(diào)用主線程中的updateProgressBar()。其實代碼如下:

              protected void updateProgressBar() {
                  
          int percent = (int) (((float) lFileCompleteSize / (float) lFileSize) * 10000F);
                  pbFile.setValue(percent);
                  
          // System.out.println("================================================="+percent);
                  pbFile.setString(lFileCompleteSize / 1024L + "/" + lFileSize / 1024L
                          
          + " kB");
                  percent 
          = (int) (((float) lTotalCompleteSize / (float) lTotalSize) * 10000F);
                  pbTotal.setString(lTotalCompleteSize 
          / 1024L + "/" + lTotalSize / 1024L
                          
          + " kB");
                  pbTotal.setValue(percent);
                  repaint();
              }

           

          上面用了兩個進度條,第一個進度條表示當前文件的上傳或下載進度,第二個進度條表示所有文件下載或上傳的進度。同時,為了產(chǎn)生進度條的移動或變化進度幅度比較明顯,通過pbFile.setMaximum(10000)pbTotal.setMaximum(10000)將進度條的最大值設置成10000,而不是平時我們所設置的100。筆者認為這樣比較好看,因為有的時候上傳或下載的時候由于網(wǎng)絡原因,可能變化比較小。若設置成100則變化不是特別明顯。


          評論

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2007-11-12 11:12 by figo
          有沒有源碼啊

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2007-12-12 18:02 by luciano
          可以詳細講一下進度條的內(nèi)容嗎?我如何才能顯示進度條?能否給個加進度條的例子

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二) [未登錄]  回復  更多評論   

          2007-12-14 17:22 by 王磊
          大哥,能給個全部的源碼么?我看了你的演示,很不錯,適合我現(xiàn)在的需求,萬分感謝!我的郵箱是 wangl@95068.com

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2008-06-16 15:28 by 逸誠
          哥們,非常佩服你的才華。非常棒,能否將全部源碼和文檔給我發(fā)一份,我認真學習一下,不勝感激之至。我的郵箱是jnflxdx@163.com或者519899460@qq.com。

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二) [未登錄]  回復  更多評論   

          2009-02-05 23:18 by liwei
          哥們,非常佩服你的才華。非常棒,能否將全部源碼和文檔給我發(fā)一份,我認真學習一下,不勝感激之至。我的郵箱是109626532@163.com

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2009-07-11 21:37 by
          樓主,太強了。能不能讓我也學習一下。能發(fā)份源代碼給我嗎?我的郵箱是408985552@qq.com,不甚感激??!

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2011-01-14 14:18 by Glorin
          樓主你好哇?看了你的演示非常棒!你可以把全部源碼都發(fā)一份給我嗎?我好好研究一下,非常感謝。我的郵箱是350643976@qq.com

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2011-09-02 11:09 by 徐強
          能否發(fā)一份源碼給我.萬分感謝!qiangzi1110@126.com

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2011-09-15 21:50 by 維拉斯
          樓主,太強了。能不能讓我也學習一下。能發(fā)份源代碼給我嗎?我的郵箱是yushuffoo@163.com,不甚感激??!

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2012-01-14 14:41 by 婷婷
          跪求一份全部源碼,不甚感激,著急使用謝謝啦!1936330494@qq.com

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2012-05-22 16:32 by shanyiyatou
          為什么上傳的時候會有亂碼呢

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二) [未登錄]  回復  更多評論   

          2012-08-05 10:00 by derekzhan
          兄弟能不能給我傳一份源碼~ zhanweichun@126.com 不勝感激!!

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2013-05-18 21:57 by 岳曉西
          樓主,您好,能否給俺也發(fā)一份呀,學習,不慎感激 郵箱:949752584@qq.com

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二) [未登錄]  回復  更多評論   

          2013-09-30 09:23 by 小白
          718589908@qq.com 坐等

          # re: 用Java實現(xiàn)FTP批量大文件上傳下載(二)   回復  更多評論   

          2014-11-09 22:28 by 馬成虎
          樓主能給菜鳥發(fā)一份嗎? 郵箱:2425643701@qq.com
          主站蜘蛛池模板: 乐陵市| 兴文县| 桃江县| 霍山县| 竹山县| 塘沽区| 武山县| 上饶市| 永靖县| 依兰县| 黔江区| 且末县| 西贡区| 连江县| 肥城市| 阳朔县| 马尔康县| 榕江县| 南投市| 三亚市| 渭源县| 稻城县| 蓬莱市| 石柱| 宁远县| 上饶市| 商南县| 定陶县| 虹口区| 平昌县| 左云县| 共和县| 木兰县| 班戈县| 南京市| 封丘县| 灵台县| 和田县| 加查县| 油尖旺区| 台中县|