今天同事问我一个ftp 上传文件和下载文件功能应该怎么做,当时有点懵逼,毕竟我也是第一次,然后装了个逼,在网上找了一段代码发给同事,叫他调试一下。结果悲剧了,运行不通过。(装逼失败)

我找的文章链接:

为了方便大家对比,我吧文章代码偷了过来:




java代码通过连接下载PDF文件显示文件已损坏 javaftp下载文件_java

java代码通过连接下载PDF文件显示文件已损坏 javaftp下载文件_System_02

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", "user@", "/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贴出来:




java代码通过连接下载PDF文件显示文件已损坏 javaftp下载文件_java

java代码通过连接下载PDF文件显示文件已损坏 javaftp下载文件_System_02

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


错误log


有兴趣的可以研究一下,希望找到原因的可以告诉一下博主,谢谢。
尽管博主装逼失败,但逼装了,还是要继续装下去的,于是,找到了以下的办法,博主亲测成功,不成功可以联系博主。不多说直接贴代码:
用到的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);
    }
}