1. 程式人生 > >用Java實現FTP批量大檔案上傳下載(一)

用Java實現FTP批量大檔案上傳下載(一)

本文介紹了在Java中,如何使用Java現有的可用的庫來編寫FTP客戶端程式碼,並開發成Applet控制元件,做成基於Web的批量、大檔案的上傳下載控制元件。文章在比較了一系列FTP客戶庫的基礎上,就其中一個比較通用且功能較強的j-ftp類庫,對一些比較常見的功能如進度條、斷點續傳、內外網的對映、在Applet中回撥JavaScript函式等問題進行詳細的闡述及程式碼實現,希望通過此文起到一個拋磚引玉的作用。

一、        引子

筆者在實施一個專案過程中出現了一種基於Web的檔案上傳下載需求。在全省(或全國)各地的使用者,需要將一些檔案上傳至某中心的檔案伺服器上。這些檔案是用於一些大型的工程建設,可能涉及到上千萬甚至上億的建設工程。檔案具有三個鮮明的特徵:一是檔案大,可能達到50M;二是檔案數量多,有可能15個左右;三是資料安全性方面要求數字簽名及資料加密。

首先考慮到是基於HTTP的傳輸方式。但筆者通過比較很快發現滿足上面的需求:

1:用HTTP協議上傳,似乎更適合web程式設計的方便性;上傳小於1M檔案速度要比用FTP協議上傳檔案略快。但對於批量及大檔案的傳輸可能無能為力。當然,它也有它的優勢,如不像FTP那樣,必須在伺服器端啟動一個FTP服務。

2:用FTP協議上傳檔案大於1M的檔案速度比HTTP快。檔案越大,上傳的速度就比HTTP上傳的速度快數倍。而且用java編寫程式;FTP比HTTP方便。

筆者曾經使用VB也寫過ActiveX控制元件來進行批量檔案的上傳下載,其功能也很強大。只是由於沒有對CAB檔案或OCX進行專門的數字簽名,因此需要進行客戶端煩瑣的設定,如設定安全站點、降低客戶端的安全級別等等,因而放棄了些方案。

同時考慮到在需在客戶端對檔案進行數字簽名及資料加密,決定採用Applet的方式實現。。檔案上傳之前,在客戶端可以獲取本地USBKEY金鑰資訊,完成對上傳檔案的加密和簽名處理。雖然採用Applet要求在客戶端安裝JRE執行時環境,給客戶端的管理及使用帶來一度的不方便性,但是相對起如此大量的檔案及檔案的安全性,這也許已經算是比較小的代價了。

總結一下執行的環境為:

FTP伺服器端:Serv-U,專業的FTP伺服器端程式,網上有現成的軟體下載,當然讀者也可能自己寫一個伺服器端的FTP檔案接收程式來進行解釋。如果沒有特殊要求或功能的話,Serv-U應該可以滿足我們一般上傳下載的需求了;

客戶端:Java applet,當年讓Java大火了一把的號稱與微軟的ActiveX相提並論的技術當然,現在Java出了JavaFX,是不是Applet的替代品呢?

應用環境:Internet網,最終目的。

二、        Java FTP客戶端庫的選擇

讓我們設想這樣一個情形--我們想寫一個純Java的從一個遠端計算機上執行的FTP伺服器上傳下載檔案的應用程式;我們還希望能夠得到那些供下載的遠端檔案的基本檔案資訊,如檔名、資料或者檔案大小等。

儘管從頭開始寫一個FTP協議處理程式是可能的,並且也許很有趣,但這項工作也是困難、漫長並且存在著潛在的危險。因為我們不願意親自花時間、精力、或者金錢去寫這樣的一個處理程式,所以我們轉而採用那些已經存在的可重用的元件。並且很多的庫存在於網上。

找一個優秀的適合我們需要的Java FTP 客戶端庫並不像看起來那麼簡單。相反這是一項非常痛苦複雜的工作。首先找到一個FTP客戶端庫需要一些時間,其次,在我們找到所有的存在的庫後,我們該選哪一個呢?每個庫都適合不同的需求。這些庫在效能上是不等價的,並且它們的設計上有著根本上的差別。每個類庫都各具特點並使用不同的術語來描述它們。因而,評價和比較FTP客戶端庫是一件困難的事情。

使用可重用元件是一種值得提倡的方法,但是在這種情況下,剛開始往往是令人氣餒的。後來或許有點慚愧:在選擇了一個好的FTP庫後,其後的工作就非常簡單了,按簡單的規則來就行了。目前,已經有很多公開免費的ftp客戶端類庫,如simpleftp、J-ftp等,還有很多其他的ftpclient。如下表所示,表中未能全部列出,如讀者有更好的客戶端FTP類庫,請進行進一步的補充。

FTP客戶端類庫名

備註

J-ftp

J-ftp

ftpclient

com.enterprisedt.net.ftp.FTPClient

FTPProtocol

com.ibm.network.ftp.protocol.FTPProtocol

FtpConnection 

net.sf.jftp.net.FtpConnection

FTPClient

org.apache.commons.net.ftp.FTPClient

FTPClient 

jshop.jnet.FTPClient

FtpClient 

sun.net.ftp.FtpClient 

FTP 

com.cqs.ftp.FTP 

Ftp

cz.dhl.ftp.Ftp

FTPClient

org.globus.io.ftp.FTPClient

在本文中,筆者採用是J-ftp。這個是個開源的且功能十分強大的客戶端FTP類庫。筆者很喜歡,同時也向各位讀者推薦一下。算了免費為它做一個廣告。

三、        基本功能

1、 登陸

採用FTP進行檔案傳輸,其實本質上還是採用Java.net.socket進行通訊。以下程式碼只是類net.sf.jftp.net.FtpConnection其中一個login方法。當然在下面的程式碼,為了節省版面,以及將一些原理闡述清楚,筆者將一些沒必要的程式碼去掉了,如日誌等程式碼。完整的程式碼請參考J-ftp的原始碼或是筆者所以的示例原始碼,後面的程式碼示例也同理:

public int login(String username, String password)
    {
        this.username = username;
        this.password = password;

        int status = LOGIN_OK;

        jcon = new JConnection(host, port);

        if(jcon.isThere())
        {
            in = jcon.getReader();

            if(getLine(POSITIVE) == null)//FTP220_SERVICE_READY) == null)
            {
                ok = false;                
                status = OFFLINE;
            }
   

            if(!getLine(loginAck).startsWith(POSITIVE))//FTP230_LOGGED_IN))
            {               
                if(success(POSITIVE))//FTP230_LOGGED_IN))
                {                 
                }

                else
                {
                    ok = false;
                    status = WRONG_LOGIN_DATA;
                }

            }

        }

        else
        {
            if(msg)
            {
                Log.debug("FTP not available!");
                ok = false;
                status = GENERIC_FAILED;
            }

        }


        if(ok)
        {
            connected = true;
            system();
            binary();
            
            String[] advSettings = new String[6];

            if(getOsType().indexOf("OS/2") >= 0)
            {
                LIST_DEFAULT = "LIST";
            }


            if(LIST.equals("default"))
            {
                //just get the first item (somehow it knows first is the
                
//FTP list command)
                advSettings = LoadSet.loadSet(Settings.adv_settings);

                //*** IF FILE NOT FOUND, CREATE IT AND SET IT TO LIST_DEFAULT
                if(advSettings == null)
                {
                    LIST = LIST_DEFAULT;

                    SaveSet s = new SaveSet(Settings.adv_settings, LIST);
                }

                else
                {
                    LIST = advSettings[0];

                    if(LIST == null)
                    {
                        LIST = LIST_DEFAULT;
                    }

                }

            }


            if(getOsType().indexOf("MVS") >= 0)
            {
                LIST = "LIST";
            }


            //***
            fireDirectoryUpdate(this);
            fireConnectionInitialized(this);
        }

        else
        {
            fireConnectionFailed(thisnew Integer(status).toString());
        }


        return status;
    }

此登陸方法中,有一個JConnection類,此類負責建立socket套接字    ,同時,此類是一種單獨的執行緒,這樣的好處是為了配合介面的變化,而將網路的套接字連線等工作做為單獨的執行緒來處理,有利於介面的友好性。下面是net.sf.jftp.net.JConnection類的run方法,當然,此執行緒的啟動是在JConnection類的構造方法中啟動的。
    public void run()
    {
        try
        {
            s = new Socket(host, port);

            localPort = s.getLocalPort();

            //if(time > 0) s.setSoTimeout(time);
            out = new PrintStream(new BufferedOutputStream(s.getOutputStream(),
                                                           Settings.bufferSize));
            in = new BufferedReader(new InputStreamReader(s.getInputStream()),
                                    Settings.bufferSize);
            isOk = true;

            // }
        }

        catch(Exception ex)
        {
            ex.printStackTrace();
            Log.out("WARNING: connection closed due to exception (" + host +
                    ":" + port + ")");
            isOk = false;

            try
            {
                if((s != null) && !s.isClosed())
                {
                    s.close();
                }


                if(out != null)
                {
                    out.close();
                }


                if(in != null)
                {
                    in.close();
                }

            }

            catch(Exception ex2)
            {
                ex2.printStackTrace();
                Log.out("WARNING: got more errors trying to close socket and streams");
            }

        }


        established = true;
    }

 

此run方法中的socket這裡說明一下,此類實現客戶端套接字(也可以就叫“套接字”),套接字是兩臺機器之間的通訊端點。套接字的實際工作由 SocketImpl 類的例項執行。應用程式通過更改建立套接字實現的套接字工廠可以配置它自身,以建立適合本地防火牆的套接字。具體的說明請參考JDK5 的API說明,最好是中文的。呵呵。



相關推薦

Java實現FTP批量檔案下載()

本文介紹了在Java中,如何使用Java現有的可用的庫來編寫FTP客戶端程式碼,並開發成Applet控制元件,做成基於Web的批量、大檔案的上傳下載控制元件。文章在比較了一系列FTP客戶庫的基礎上,就其中一個比較通用且功能較強的j-ftp類庫,對一些比較常見的功能如進度條、

Java實現FTP批量檔案下載(四)

六、FTP埠對映 FTP的資料連線有PASV和PORT兩種,如果你的FTP伺服器位於內網中,需要做埠對映。筆者剛開始時對FTP的網外網對映也是不怎麼了解,因此開始走了不少的彎路,開始一直以為是自己的程式有問題,浪費了不少時間,希望通過這段,能讓大家在開發的時候少花或不花這些

Java實現FTP批量檔案下載(五) --執行效果圖

八、執行效果   1.上傳 (1).啟動上傳上面 (2).上傳中 (3).上傳中 (4).上傳成功 2.下載 (1)下載檔案的儲存路徑 (2)下載中 (3)下載中 (4)下載成功 九、小結 在本文中,筆者將在實際專案中的上傳下載

Java實現FTP批量檔案下載(五)

八、執行效果   1.上傳 (1).啟動上傳上面 (2).上傳中 (3).上傳中 (4).上傳成功 2.下載 (1)下載檔案的儲存路徑 (2)下載中  (3)下載中  (4)下載成功 九、小結 在本文中,筆者將在實際專案中的上傳下載問題的解決方案進行了闡述,通過採用FTP協

Java 使用 FTP 實現檔案下載

Java 上傳下載 1G 以上的檔案可以通過 http 協議或 ftp 實現,但是 http 協議對檔案上傳大小有限制,而且還不穩定,因此這裡使用 ftp 上傳。 ftp 上傳方式有兩種: 一、ASCII 傳輸方式:假定使用者正在拷貝的檔案包含

Java實現的SFTP(檔案詳解篇)

JSch是Java Secure Channel的縮寫。JSch是一個SSH2的純Java實現。它允許你連線到一個SSH伺服器,並且可以使用埠轉發,X11轉發,檔案傳輸等,當然你也可以整合它的功能到你自己的應用程式。 本文只介紹如何使用JSch實現的SFTP功能

基於Java的一個簡單的檔案下載功能

最近在公司給客戶端做介面,有一個圖片上傳和檔案下載的功能,本來想用Struts來做檔案上傳下載,但是看了下公司好像沒有這個配置,然後看了下同事的程式碼,才發現原來Apache也可以簡單的實現檔案上傳下載。 首先引入commons-io-2.2.jar FileUtils為我

Linux系統安裝rz/sz實現本地和伺服器檔案下載

一:說明     通過SecureCRT等SSH登入軟體連線伺服器,可以通過rz和sz命令上傳下載檔案,就不需要通過xftp進行檔案操作了. sz 檔名: 將選定的檔案傳送(send)到本地

java實現ftp檔案

實際專案需求:從資料庫查詢資訊,在本地生成檔案,再上傳到ftp 所用Jar包:NetComponents.jar 核心程式碼: import java.io.File; import java.io.FileInputStream; import java.io.IOExcepti

java實現檔案

檔案上傳是最古老的網際網路操作之一,20多年來幾乎沒有怎麼變化,還是操作麻煩、缺乏互動、使用者體驗差。 一、前端程式碼 英國程式設計師Remy Sharp總結了這些新的介面 ,本文在他的基礎之上,討論在前端採用HTML5的API,對檔案上傳進行漸進式增強: * iframe上傳    *

java實現從txt文字檔案批量匯入資料至資料庫

今天同事讓我準備一個專案的測試資料,要向一個表中插入上千條記錄,並且保證每條記錄內容不同,如果用手工一條一條插入肯定是不可能,也不會有哪個SB去做這樣的事,我最開始想到了用迴圈,但要求插入的記錄內容不能相同,用迴圈實現比較麻煩,於是我想到了將記錄從文字檔案匯入至資料庫(其實

java實現檔案下載ftp伺服器

以前做的一個專案,用到了檔案上傳下載至ftp伺服器,現在對其進行一下複習,比較簡單,一下就能看明白。 環境:首先,先安裝ftp伺服器,我是在win8本地用IIS配置的, 百度一下就可以找到安裝文件。 1.在你的專案目錄下建立ftp配置檔案,目錄如下圖

JAVA實現批量更改檔案字尾名的程式

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

前端元件WebUploader檔案與Python結合的實現

Python實現大檔案分片上傳 引言 想借著這篇文章簡要談談WebUploader大檔案上傳與Python結合的實現。 WebUploader是百度團隊對大檔案上傳的前端實現,而後端需要根據不同的語言自己實現。這裡我採用Python語言的Flask框架搭建後端,

C#實現檔案功能(二)---webuploader

                                        一、問題來源 近些時候,處理專案的時候發現如果使用者上傳大檔案的時候使用HtmlInputFile通過httppostfilebase 來實現上傳,如果檔案較小的話較小的話,上傳沒有問題(4M)

Ftp實現自動讀取本地檔案到伺服器

需求:最近有個需求,類似需要將pre環境的oracle檔案,放到prd環境中hive叢集中儲存,但是因為資料來源和資料儲存節點不在一個環境中,所以無法通訊配置實現資料的直接傳輸。 解決方案:  1.寫指令碼自動將oracle中資料寫入到本地指定資料夾。  2.通過

Java實現檔案下載的三種解決方案

第一點:Java程式碼實現檔案上傳   FormFile file=manform.getFile();    String newfileName = null;   String newpathname=null;   String fileAddre="/numU

JAVA NIO SOCKET檔案伺服器

        當前很多手機應用或者是網路應用都需要支援大檔案上傳功能,有些用FTP來實現上傳但是FTP存在許多的問題。比如FTP的安全問題還有不支援GZIP壓縮等問題。採用SOCKET來實現檔案上傳,很輕鬆就可以實現斷點再續和負載均衡,將上傳後的檔案直接儲存到APACHE

java socket 實現c/s檔案下載功能+註冊登入

使用JAVA SOCKET實現c/s結構的通訊程式,以實現客戶端向伺服器端的檔案的上傳以及伺服器端向客戶端的檔案的下載。 實現思路: 1、在伺服器端,建立SocketServer物件,監聽某一埠,有連線請求則開一個執行緒處理這一請求 2、在客戶端,根據伺服器的ip地址以及埠號,建立

java ftp檔案下載刪除

package ftp; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStre