1. 程式人生 > >Java ftp 上傳檔案和下載檔案

Java ftp 上傳檔案和下載檔案

今天同事問我一個ftp 上傳檔案和下載檔案功能應該怎麼做,當時有點懵逼,畢竟我也是第一次,然後裝了個逼,在網上找了一段程式碼發給同事,叫他除錯一下。結果悲劇了,執行不通過。(裝逼失敗)

我找的文章連結:http://blog.csdn.net/yucaifu1989/article/details/51483118

為了方便大家對比,我吧文章程式碼偷了過來:

複製程式碼

import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.net.InetSocketAddress;  
import sun.net.TelnetInputStream;  
import sun.net.TelnetOutputStream;  
import sun.net.ftp.FtpClient;  
import sun.net.ftp.FtpProtocolException;  
/** 
 * Java自帶的API對FTP的操作 
 * @Jdk:version 1.7 
 * @Title:Ftp.java 
 * @author: boonya 
 * @notice: 貌似此方法有個缺陷,不能操作大檔案 
 */  
public class FtpJdk  
{  
    /** 
     *  
     * 本地檔名 
     */  
    private String localfilename;  
    /** 
     *  
     * 遠端檔名 
     */  
    private String remotefilename;  
    /** 
     *  
     * FTP客戶端 
     */  
    private FtpClient ftpClient;  
  
    /** 
     * 伺服器連線 
     *  
     * @param ip 
     *            伺服器IP 
     * @param port 
     *            伺服器埠 
     * @param user 
     *            使用者名稱 
     * @param password 
     *            密碼 
     * @param path 
     *            伺服器路徑 
     * @throws FtpProtocolException 
     *  
     */  
    public void connectServer(String ip, int port, String user, String password, String path) throws FtpProtocolException  
    {  
        try  
        {  
            /* ******連線伺服器的兩種方法****** */  
            // 第一種方法  
            /* 
             * ftpClient =FtpClient.create(); 
             * ftpClient.connect(new InetSocketAddress(ip, port)); 
             */  
            // 第二種方法  
            ftpClient = FtpClient.create(ip);  
            ftpClient.login(user, null, password);  
            // 設定成2進位制傳輸  
            ftpClient.setBinaryType();  
            System.out.println("login success!");  
  
            if (path.length() != 0)  
            {  
                // 把遠端系統上的目錄切換到引數path所指定的目錄  
                ftpClient.changeDirectory(path);  
            }  
            ftpClient.setBinaryType();  
        } catch (IOException ex)  
        {  
            ex.printStackTrace();  
            throw new RuntimeException(ex);  
        }  
  
    }  
  
    /** 
     * 關閉連線 
     *  
     */  
  
    public void closeConnect()  
    {  
        try  
        {  
            ftpClient.close();  
            System.out.println("disconnect success");  
        } catch (IOException ex)  
        {  
            System.out.println("not disconnect");  
            ex.printStackTrace();  
            throw new RuntimeException(ex);  
        }  
    }  
  
    /** 
     *  
     * 上傳檔案 
     *  
     * @param localFile 
     *            本地檔案 
     * @param remoteFile 
     *            遠端檔案 
     * @throws FtpProtocolException 
     */  
    public void upload(String localFile, String remoteFile) throws FtpProtocolException  
    {  
        this.localfilename = localFile;  
        this.remotefilename = remoteFile;  
        TelnetOutputStream os = null;  
        FileInputStream is = null;  
        try  
        {  
            // 將遠端檔案加入輸出流中  
            os = (TelnetOutputStream) ftpClient.putFileStream(this.remotefilename, true);  
  
            // 獲取本地檔案的輸入流  
            File file_in = new File(this.localfilename);  
            is = new FileInputStream(file_in);  
  
            // 建立一個緩衝區  
            byte[] bytes = new byte[1024];  
            int c;  
            while ((c = is.read(bytes)) != -1)  
            {  
                os.write(bytes, 0, c);  
            }  
            System.out.println("upload success");  
        } catch (IOException ex)  
        {  
            System.out.println("not upload");  
            ex.printStackTrace();  
            throw new RuntimeException(ex);  
        } finally  
        {  
            try  
            {  
                if (is != null)  
                {  
                    is.close();  
                }  
            } catch (IOException e)  
            {  
                e.printStackTrace();  
            } finally  
            {  
                try  
                {  
                    if (os != null)  
                    {  
                        os.close();  
                    }  
                } catch (IOException e)  
                {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
  
    /** 
     *  
     * 下載檔案 
     *  
     * @param remoteFile 
     *            遠端檔案路徑(伺服器端) 
     * @param localFile 
     *            本地檔案路徑(客戶端) 
     * @throws FtpProtocolException 
     *  
     */  
    public void download(String remoteFile, String localFile) throws FtpProtocolException  
    {  
        TelnetInputStream is = null;  
        FileOutputStream os = null;  
        try  
        {  
  
            // 獲取遠端機器上的檔案filename,藉助TelnetInputStream把該檔案傳送到本地。  
            is = (TelnetInputStream) ftpClient.getFileStream(remoteFile);  
            File file_in = new File(localFile);  
            os = new FileOutputStream(file_in);  
  
            byte[] bytes = new byte[1024];  
            int c;  
            while ((c = is.read(bytes)) != -1)  
            {  
                os.write(bytes, 0, c);  
            }  
            System.out.println("download success");  
        } catch (IOException ex)  
        {  
            System.out.println("not download");  
            ex.printStackTrace();  
            throw new RuntimeException(ex);  
        } finally  
        {  
            try  
            {  
                if (is != null)  
                {  
                    is.close();  
                }  
            } catch (IOException e)  
            {  
                e.printStackTrace();  
            } finally  
            {  
                try  
                {  
                    if (os != null)  
                    {  
                        os.close();  
                    }  
                } catch (IOException e)  
                {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
  
    /** 
     * 函式入口 
     *  
     * @param agrs 
     */  
    public static void main(String agrs[])  
    {  
  
        String filepath[] =  
        { "/temp/aa.txt", "/temp/regist.log" };  
        String localfilepath[] =  
        { "C:\\tmp\\1.txt", "C:\\tmp\\2.log" };  
        FtpJdk ftp = new FtpJdk();  
        /* 
         * 使用預設的埠號、使用者名稱、密碼以及根目錄連線FTP伺服器 
         */  
        try  
        {  
            ftp.connectServer("127.0.0.1", 22, "boonya", "
[email protected]
", "/temp"); } catch (FtpProtocolException e) { e.printStackTrace(); } // 下載 for (int i = 0; i < filepath.length; i++) { try { ftp.download(filepath[i], localfilepath[i]); } catch (FtpProtocolException e) { e.printStackTrace(); } } String localfile = "E:\\contact.txt"; String remotefile = "/temp/records.txt"; // 上傳 try { ftp.upload(localfile, remotefile); } catch (FtpProtocolException e) { e.printStackTrace(); } ftp.closeConnect(); } }

複製程式碼

順便把錯誤的log貼出來:

複製程式碼

sun.net.ftp.FtpProtocolException: TYPE I:530 Please login with USER and PASS.

    at sun.net.ftp.impl.FtpClient.issueCommandCheck(FtpClient.java:544)
    at sun.net.ftp.impl.FtpClient.setType(FtpClient.java:1668)
    at sun.net.ftp.FtpClient.setBinaryType(FtpClient.java:676)
    at ftp.FtpJdk.connectServer(FtpJdk.java:67)
    at ftp.FtpJdk.main(FtpJdk.java:248)
not upload
Disconnected from the target VM, address: '127.0.0.1:49353', transport: 'socket'
java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
    at sun.net.ftp.impl.FtpClient.readServerResponse(FtpClient.java:420)
    at sun.net.ftp.impl.FtpClient.readReply(FtpClient.java:497)
    at sun.net.ftp.impl.FtpClient.issueCommand(FtpClient.java:532)
    at sun.net.ftp.impl.FtpClient.issueCommandCheck(FtpClient.java:543)
    at sun.net.ftp.impl.FtpClient.openDataConnection(FtpClient.java:757)
    at sun.net.ftp.impl.FtpClient.putFileStream(FtpClient.java:1320)
    at ftp.FtpJdk.upload(FtpJdk.java:122)
    at ftp.FtpJdk.main(FtpJdk.java:269)
Exception in thread "main" java.lang.RuntimeException: java.net.SocketTimeoutException: Read timed out
    at ftp.FtpJdk.upload(FtpJdk.java:140)
    at ftp.FtpJdk.main(FtpJdk.java:269)
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
    at sun.net.ftp.impl.FtpClient.readServerResponse(FtpClient.java:420)
    at sun.net.ftp.impl.FtpClient.readReply(FtpClient.java:497)
    at sun.net.ftp.impl.FtpClient.issueCommand(FtpClient.java:532)
    at sun.net.ftp.impl.FtpClient.issueCommandCheck(FtpClient.java:543)
    at sun.net.ftp.impl.FtpClient.openDataConnection(FtpClient.java:757)
    at sun.net.ftp.impl.FtpClient.putFileStream(FtpClient.java:1320)
    at ftp.FtpJdk.upload(FtpJdk.java:122)
    ... 1 more

複製程式碼

有興趣的可以研究一下,希望找到原因的可以告訴一下博主,謝謝。

儘管博主裝逼失敗,但逼裝了,還是要繼續裝下去的,於是,找到了以下的辦法,博主親測成功,不成功可以聯絡博主。不多說直接貼程式碼:

用到的jar:

commons-net-1.4.1.jar

maven下載

<dependency>     <groupId>commons-net</groupId>     <artifactId>commons-net</artifactId>     <version>1.4.1</version> </dependency>

ftp工具類:

複製程式碼

package ftp.ftp2;


import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpProtocolException;

import java.io.*;
import java.net.SocketException;
import java.util.Properties;



public class FtpUtil {

    /**
     * 獲取FTPClient物件
     *
     * @param ftpHost     FTP主機伺服器
     * @param ftpPassword FTP 登入密碼
     * @param ftpUserName FTP登入使用者名稱
     * @param ftpPort     FTP埠 預設為21
     * @return
     */
    public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
                                         String ftpPassword, int ftpPort) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpHost, ftpPort);// 連線FTP伺服器
            ftpClient.login(ftpUserName, ftpPassword);// 登陸FTP伺服器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                System.out.println("未連線到FTP,使用者名稱或密碼錯誤。");
                ftpClient.disconnect();
            } else {
                System.out.println("FTP連線成功。");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            System.out.println("FTP的IP地址可能錯誤,請正確配置。");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("FTP的埠錯誤,請正確配置。");
        }
        return ftpClient;
    }

    /*
     * 從FTP伺服器下載檔案
     *
     * @param ftpHost FTP IP地址
     * @param ftpUserName FTP 使用者名稱
     * @param ftpPassword FTP使用者名稱密碼
     * @param ftpPort FTP埠
     * @param ftpPath FTP伺服器中檔案所在路徑 格式: ftptest/aa
     * @param localPath 下載到本地的位置 格式:H:/download
     * @param fileName 檔名稱
     */
    public static void downloadFtpFile(String ftpHost, String ftpUserName,
                                       String ftpPassword, int ftpPort, String ftpPath, String localPath,
                                       String fileName) {

        FTPClient ftpClient = null;

        try {
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            ftpClient.setControlEncoding("UTF-8"); // 中文支援
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);

            File localFile = new File(localPath + File.separatorChar + fileName);
            OutputStream os = new FileOutputStream(localFile);
            ftpClient.retrieveFile(fileName, os);
            os.close();
            ftpClient.logout();

        } catch (FileNotFoundException e) {
            System.out.println("沒有找到" + ftpPath + "檔案");
            e.printStackTrace();
        } catch (SocketException e) {
            System.out.println("連線FTP失敗.");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("檔案讀取錯誤。");
            e.printStackTrace();
        }

    }

    /**
     * Description: 向FTP伺服器上傳檔案
     * @param ftpHost FTP伺服器hostname
     * @param ftpUserName 賬號
     * @param ftpPassword 密碼
     * @param ftpPort 埠
     * @param ftpPath  FTP伺服器中檔案所在路徑 格式: ftptest/aa
     * @param fileName ftp檔名稱
     * @param input 檔案流
     * @return 成功返回true,否則返回false
     */
    public static boolean uploadFile(String ftpHost, String ftpUserName,
                                     String ftpPassword, int ftpPort, String ftpPath,
                                     String fileName,InputStream input) {
        boolean success = false;
        FTPClient ftpClient = null;
        try {
            int reply;
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return success;
            }
            ftpClient.setControlEncoding("UTF-8"); // 中文支援
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);

            ftpClient.storeFile(fileName, input);

            input.close();
            ftpClient.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

}

複製程式碼

測試類:

複製程式碼

package ftp.ftp2;

import java.io.*;

/**
 * Created by jyf on 2017/6/2.
 */
public class test {
    public static void main(String[] args) {
        String ftpHost = "172.16.114.10";
        String ftpUserName = "user";
        String ftpPassword = "a";
        int ftpPort = 21;
        String ftpPath = "test2/";
        String localPath = "F:\\11.txt";
        String fileName = "11.txt";

        //上傳一個檔案
        try{
            FileInputStream in=new FileInputStream(new File(localPath));
            boolean test = FtpUtil.uploadFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName,in);
            System.out.println(test);
        } catch (FileNotFoundException e){
            e.printStackTrace();
            System.out.println(e);
        }

        //在FTP伺服器上生成一個檔案,並將一個字串寫入到該檔案中
        try {
            InputStream input = new ByteArrayInputStream("test ftp jyf".getBytes("GBK"));
            boolean flag = FtpUtil.uploadFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName,input);;
            System.out.println(flag);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //下載一個檔案
        FtpUtil.downloadFtpFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, localPath, fileName);
    }
}