1. 程式人生 > >Java 使用 FTP 實現大檔案上傳下載

Java 使用 FTP 實現大檔案上傳下載

Java 上傳下載 1G 以上的檔案可以通過 http 協議或 ftp 實現,但是 http 協議對檔案上傳大小有限制,而且還不穩定,因此這裡使用 ftp 上傳。
ftp 上傳方式有兩種:
一、ASCII 傳輸方式:假定使用者正在拷貝的檔案包含的簡單ASCII碼文字,如果在遠端機器上執行的不是UNIX,當檔案傳輸時ftp通常會自動地調整檔案的內容以便於把檔案解釋成另外那臺計算機儲存文字檔案的格式。
       但是常常有這樣的情況,使用者正在傳輸的檔案包含的不是文字檔案,它們可能是程式,資料庫,字處理檔案或者壓縮檔案(儘管字處理檔案包含的大部分是文字,其中也包含有指示頁尺寸,字型檔等資訊的非列印字元)。在拷貝任何非文字檔案之前,用binary 命令告訴ftp逐字拷貝,不要對這些檔案進行處理,這也是下面要講的二進位制傳輸
二、二進位制傳輸方式:在二進位制傳輸中,儲存檔案的位序,以便原始和拷貝的是逐位一一對應的。即使目的地機器上包含位序列的檔案是沒意義的。例如,macintosh以二進位制方式傳送可執行檔案到IBM VM系統,在對方系統上,此檔案不能執行。(但是,它可以從VM系統上以二進位制方式拷貝到另一macintosh,是可以執行的)。
       如果你在ASCII方式下傳輸二進位制檔案,即使不需要也仍會轉譯。這會使傳輸稍微變慢 ,也會損壞資料,使檔案變得不能用。(在大多數計算機上,ASCII方式一般假設每一字元的第一有效位無意義,因為ASCII字元組合不使用它。如果你傳輸二進位制檔案,所有的位都是重要的。)如果你知道這兩臺機器是同樣的,則二進位制方式對文字檔案和資料檔案都是有效的。
       因此,這就意謂著知道你要傳輸的是什麼型別的資料是重要的,下列給出一些常見檔案型別的提示

檔案 方式
Text file ASCII
Spreadsheet 大多是二進位制
Database file 大多是二進位制,也可能是ASCII
Word processor file 大多是二進位制,也可能是ASCII
Program source code ASCII
Electronic mail messages ASCII
UNIX“shell archive” ASCII
UNIX“tar file” 二進位制
backup file 二進位制
Compressed file 二進位制
Unencoded file ASCII
Excutable file 二進位制
Postscript file 二進位制

很多資料庫程式用二進位制格式存貯資料,即使資料原本是文字式。所以,除非你知道你的軟體的用途,我們建議對資料庫檔案先用二進位制方式試試。然後看看你傳輸的檔案能否正確工作。如果不能,再試用另一方式。可執行的檔案一般是二進位制檔案。
轉至:文章出處

在寫程式碼之前需要配置 FTP 服務,不然 FTP 用不了,具體配置百度,這個很簡單。FTP 檔案上傳需要依賴:commons-net,我這裡用的是3.6,算是比較新的了

FTP 實現檔案上傳下載程式碼如下

package com.feicuiedu.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

/**
 * 使用 FTP 實現檔案上傳下載<br>
 * @author admin
 *
 */
public class FavFTPUtil {

    /**
     * 上傳檔案(可供Action/Controller層使用)
     * 
     * @param hostname
     *            FTP伺服器地址
     * @param port
     *            FTP伺服器埠號
     * @param username
     *            FTP登入帳號
     * @param password
     *            FTP登入密碼
     * @param pathname
     *            FTP伺服器儲存目錄
     * @param fileName
     *            上傳到FTP伺服器後的檔名稱
     * @param inputStream
     *            輸入檔案流
     * @return
     */
    public static boolean uploadFile(String hostname, int port, String username, String password, String pathname,
            String fileName, InputStream inputStream) {
        boolean flag = false;
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("UTF-8");
        try {
            // 連線FTP伺服器
            ftpClient.connect(hostname, port);
            // 登入FTP伺服器
            ftpClient.login(username, password);
            // 是否成功登入FTP伺服器
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                return flag;
            }

            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.makeDirectory(pathname);
            ftpClient.changeWorkingDirectory(pathname);
            ftpClient.storeFile(fileName, inputStream);
            inputStream.close();
            ftpClient.logout();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

    /**
     * 上傳檔案(可對檔案進行重新命名)
     * 
     * @param hostname
     *            FTP伺服器地址
     * @param port
     *            FTP伺服器埠號
     * @param username
     *            FTP登入帳號
     * @param password
     *            FTP登入密碼
     * @param pathname
     *            FTP伺服器儲存目錄
     * @param filename
     *            上傳到FTP伺服器後的檔名稱
     * @param originfilename
     *            待上傳檔案的名稱(絕對地址)
     * @return
     */
    public static boolean uploadFileFromProduction(String hostname, int port, String username, String password,
            String pathname, String filename, String originfilename) {
        boolean flag = false;
        try {
            InputStream inputStream = new FileInputStream(new File(originfilename));
            flag = uploadFile(hostname, port, username, password, pathname, filename, inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 上傳檔案(不可以進行檔案的重新命名操作)
     * 
     * @param hostname
     *            FTP伺服器地址
     * @param port
     *            FTP伺服器埠號
     * @param username
     *            FTP登入帳號
     * @param password
     *            FTP登入密碼
     * @param pathname
     *            FTP伺服器儲存目錄
     * @param originfilename
     *            待上傳檔案的名稱(絕對地址)
     * @return
     */
    public static boolean uploadFileFromProduction(String hostname, int port, String username, String password,
            String pathname, String originfilename) {
        boolean flag = false;
        try {
            String fileName = new File(originfilename).getName();
            InputStream inputStream = new FileInputStream(new File(originfilename));
            flag = uploadFile(hostname, port, username, password, pathname, fileName, inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 刪除檔案
     * 
     * @param hostname
     *            FTP伺服器地址
     * @param port
     *            FTP伺服器埠號
     * @param username
     *            FTP登入帳號
     * @param password
     *            FTP登入密碼
     * @param pathname
     *            FTP伺服器儲存目錄
     * @param filename
     *            要刪除的檔名稱
     * @return
     */
    public static boolean deleteFile(String hostname, int port, String username, String password, String pathname,
            String filename) {
        boolean flag = false;
        FTPClient ftpClient = new FTPClient();
        try {
            // 連線FTP伺服器
            ftpClient.connect(hostname, port);
            // 登入FTP伺服器
            ftpClient.login(username, password);
            // 驗證FTP伺服器是否登入成功
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                return flag;
            }
            // 切換FTP目錄
            ftpClient.changeWorkingDirectory(pathname);
            ftpClient.dele(filename);
            ftpClient.logout();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.logout();
                } catch (IOException e) {

                }
            }
        }
        return flag;
    }

    /**
     * 下載檔案
     * 
     * @param hostname
     *            FTP伺服器地址
     * @param port
     *            FTP伺服器埠號
     * @param username
     *            FTP登入帳號
     * @param password
     *            FTP登入密碼
     * @param pathname
     *            FTP伺服器檔案目錄
     * @param filename
     *            檔名稱
     * @param localpath
     *            下載後的檔案路徑
     * @return
     */
    public static boolean downloadFile(String hostname, int port, String username, String password, String pathname,
            String filename, String localpath) {
        boolean flag = false;
        FTPClient ftpClient = new FTPClient();
        try {
            // 連線FTP伺服器
            ftpClient.connect(hostname, port);
            // 登入FTP伺服器
            ftpClient.login(username, password);
            // 驗證FTP伺服器是否登入成功
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                return flag;
            }
            // 切換FTP目錄
            ftpClient.changeWorkingDirectory(pathname);
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                if (filename.equalsIgnoreCase(file.getName())) {
                    File localFile = new File(localpath + "/" + file.getName());
                    OutputStream os = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(file.getName(), os);
                    os.close();
                }
            }
            ftpClient.logout();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.logout();
                } catch (IOException e) {

                }
            }
        }
        return flag;
    }

    public static void main(String[] args) {
        String hostname = "192.168.xx.xxx";
        int port = 21;
        String username = "admin";
        String password = "admin123";
        String originfilename = "/Users/admin/work/accessory/test/WIN10-64.GHO";
        boolean res = uploadFileFromProduction(hostname, port, username, password, "/test", originfilename);
//      String pathname = "E:/fileZilla";
//      String filename = "003.xlsx";
//      String localpath = "/Users/wangbt/work/accessory/OA";
//      downloadFile(hostname, port, username, password, pathname, filename, localpath);
        System.out.println(res + "=======");
    }
}

4G大檔案上傳是沒問題的,時間大約是 十分鐘,下載大檔案沒試過,但小檔案是沒問題的,改天可以試一試
轉至:程式碼出處