posts - 310, comments - 6939, trackbacks - 0, articles - 3
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
                                                  用Java實(shí)現(xiàn)FTP批量大文件上傳下載(二) 

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

          文件的上傳可以分成多線程及單線程,在單線程情況下比較簡(jiǎn)單,而在多線程的情況下,要處理的事情要多點(diǎn),同時(shí)也要小心很多。下面是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);
                  }

          }


           

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

          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);
                  }

              }



           

          至于下載的過程,因?yàn)樗巧蟼鞯哪孢^程,與上傳的方法及寫法大同小異,在些出于篇幅的考慮,并沒有將代碼列出,但其思想及思路完全一樣。請(qǐng)讀者參考源代碼。

           

            進(jìn)度條

           

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

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


           

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

              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();
              }

           

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


          評(píng)論

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          2012-05-22 16:32 by shanyiyatou
          為什么上傳的時(shí)候會(huì)有亂碼呢

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

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

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

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

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

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

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

          2014-11-09 22:28 by 馬成虎
          樓主能給菜鳥發(fā)一份嗎? 郵箱:2425643701@qq.com
          主站蜘蛛池模板: 邵东县| 唐海县| 德兴市| 汉中市| 西畴县| 尼勒克县| 且末县| 买车| 怀远县| 拜城县| 义乌市| 明水县| 菏泽市| 娄底市| 玉树县| 垣曲县| 房山区| 尼勒克县| 罗平县| 梅州市| 武平县| 信丰县| 北辰区| 海淀区| 延长县| 蒙城县| 乐东| 蒙自县| 闽清县| 富宁县| 婺源县| 昭觉县| 赣榆县| 海南省| 阜南县| 龙州县| 龙里县| 高邑县| 灌南县| 黑龙江省| 遂昌县|