系统运维系列 之实现Ftp上传下载文件(java应用)

Posted 琅晓琳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了系统运维系列 之实现Ftp上传下载文件(java应用)相关的知识,希望对你有一定的参考价值。

1 添加依赖:
首先给工程添加maven依赖,pom.xml文件中添加:

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

2 参考代码:
以下是Ftp工具类:

package com.test.util;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
 
public class FtpUtil {
    private final static Log logger = LogFactory.getLog(FtpUtil.class);  
	  
    /** 
     * 获取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服务器 
            ftpClient.setControlEncoding("UTF-8");             // 中文支持  
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);  
            ftpClient.enterLocalPassiveMode();  
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {  
                logger.info("未连接到FTP,用户名或密码错误。");  
                ftpClient.disconnect();  
            } else {  
                logger.info("FTP连接成功。");  
            }  
        } catch (SocketException e) {  
            e.printStackTrace();  
            logger.info("FTP的IP地址可能错误,请正确配置。");  
        } catch (IOException e) {  
            e.printStackTrace();  
            logger.info("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            FTP服务器上要下载的文件名称
     * @param targetFileName      FTP服务器上要下载的文件名称 
     */  
    public static void downloadFtpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, String ftpPath, String localPath, String fileName, String targetFileName) {  
  
        FTPClient ftpClient = null;  
        try {  
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);  
            ftpClient.changeWorkingDirectory(ftpPath);
            
            String f_ame = new String(fileName.getBytes("GBK"), FTP.DEFAULT_CONTROL_ENCODING);	//编码文件格式,解决中文文件名
            
            File localFile = new File(localPath + File.separatorChar + targetFileName);  
            OutputStream os = new FileOutputStream(localFile);  
            ftpClient.retrieveFile(f_ame, os);  
            os.close();  
            ftpClient.logout();  
  
        } catch (FileNotFoundException e) {  
            logger.error("没有找到" + ftpPath + "文件");  
            e.printStackTrace();  
        } catch (SocketException e) {  
            logger.error("连接FTP失败.");  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
            logger.error("文件读取错误。");  
            e.printStackTrace();  
        }  
    }
    
    /**  
     * Description:             向FTP服务器上传文件  
     * @param host              FTP服务器hostname  
     * @param port              FTP服务器端口  
     * @param username          FTP登录账号  
     * @param password          FTP登录密码  
     * @param basePath          FTP服务器基础目录 
     * @param filePath          FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath 
     * @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 result = false;  
        FTPClient ftpClient = new FTPClient();  
        try {  
            int reply;  
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);  
            ftpClient.changeWorkingDirectory(ftpPath);
            
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return result;
            }
            
            filename = new String(filename.getBytes("GBK"), FTP.DEFAULT_CONTROL_ENCODING);    //编码文件名,支持中文文件名
            //上传文件  
            if (!ftpClient.storeFile(filename, input)) {  
                return result;  
            }  
            input.close();  
            ftpClient.logout();  
            result = true;  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            if (ftpClient.isConnected()) {  
                try {  
                	ftpClient.disconnect();  
                } catch (IOException ioe) {  
                }  
            }  
        }  
        return result;  
    }
    
    public static void main(String[] args) {
        String ftpHost = "192.168.20.40";
        String ftpUserName = "test";
        String ftpPassword = "12345";
        int ftpPort = 21;
        String ftpPath = "test/";
        String fileName = "test_通知.docx";
 
        //上传一个文件
        try{
            String tmpPath = System.getProperty("java.io.tmpdir");
            FileInputStream in=new FileInputStream(new File("D:\\\\" + fileName));
            FtpUtil.uploadFile(ftpHost, ftpUserName,  ftpPassword, ftpPort, ftpPath, fileName, in);
            
            System.out.println(tmpPath);
            FtpUtil.downloadFtpFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, "E:\\\\", "test_通知.docx", "测试下载文件.docx"); 
        } catch (Exception e){
            e.printStackTrace();
            System.out.println(e);
        }
    }
}

3 注意问题:
3.1 如果连接不成功,且无法创建文件:
防火墙,问题,是否打开21端口,且是否有足够的权限,赋值777权限。
3.2 连接成功,文件能创建,但上传不了文件:
在代码中加入一行,这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。

FTPClient.enterLocalPassiveMode();

3.3 上传文件后发现,文件乱码:
在代码中加入一行 ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置上传格式。

4 参考资料:
https://blog.csdn.net/xqq580231/article/details/80046411?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-7.control Java 实现Ftp上传下载文件
https://blog.csdn.net/qq_31634461/article/details/78314314 Java代码实现FTP服务器上传文件与下载文件

以上是关于系统运维系列 之实现Ftp上传下载文件(java应用)的主要内容,如果未能解决你的问题,请参考以下文章

系统运维系列 之List实现深拷贝(java应用)

系统运维系列 之HashMap底层实现原理和应用

系统运维系列 之java控制api接口请求次数

系统运维系列 之异常抛出后代码执行问题(java应用)

系统运维系列 之Socket和ServerSocket的简单介绍(java应用)

系统运维系列 之linux中通过sed命令直接修改文件内容