FTP相关内容学习_java

FTP相关内容

简介

FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户经常遇到两个概念:”下载”(Download)和”上传”(Upload)。”下载”文件就是从远程主机拷贝文件至自己的计算机上;”上传”文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。 —— [ 百度百科 ]

java程序使用ftp

需要的jar包

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

相关代码

  • FtpParamter.java
//ftp相关参数
public class FtpParamter {
    private String host; //地址
    private int port;    //端口 
    private String user; //用户名
    private String password; //密码

    public FtpParamter() {}
    // 相关get、set方法...

}
  • FtpFile.java

import java.io.InputStream;
/**
 * ftp文件对象
 */
public class FtpFile {
    private String remoteFilePath; // ftp服务端文件路径
    private String remoteFilename; // ftp服务端文件名
    private InputStream is;
    private String localFilePath;  // 本地文件路径

    public FtpFile() {}

    // 相关get、set方法...
  • FtpUtils.java

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

import org.apache.commons.lang.CharEncoding;
import org.apache.commons.net.ftp.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.its.itone.datatools.vo.FtpFile;
import com.its.itone.datatools.vo.FtpParamter;

public class FtpUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(FtpUtils.class);
    private static FTPClient ftpclient;

    public FtpUtils() {}

    /**
     * 登录
     *
     * @param fp 相关信息对象
     * @return true-成功;false-失败
     */
    public static boolean loginFtp(final FtpParamter fp) {
        ftpclient = new FTPClient();
        try {
            ftpclient.setControlEncoding(CharEncoding.UTF_8);
            // 设置服务器名和端口
            ftpclient.connect(fp.getHost(), fp.getPort());
            int reply = ftpclient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                LOGGER.error("retrieveFile,cannot connect server");
                return false;
            }

            // 登录
            if (!ftpclient.login(fp.getUser(), fp.getPassword())) {
                LOGGER.info("retrieveFile,invalid username or password");
                return false;
            }
            ftpclient.setConnectTimeout(60000 * 20);
        } catch (Exception e) {
            LOGGER.error("retrieveFile,connect server excelption:" + e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 上传文件到ftp服务端
     *
     * @param fp   相关信息对象
     * @param file 封装好的FtpFile对象
     * @return
     * @throws Exception
     */
    public static boolean sendFile(final FtpParamter fp, final FtpFile file) throws Exception {
        // 登录
        if(!loginFtp(fp)) {
            return false;
        }
        try{
            ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
            // 传送文件
            return ftpclient.storeFile(file.getRemoteFilename(), file.getIs());
        } catch (IOException e) {
            throw e;
        } finally {
            try {
                // 解除连接
                ftpclient.disconnect();
            } catch (IOException e) {
                LOGGER.error("error:" + e.getMessage(), e);
            }
        }
    }

    /**
     * 下载远程文件夹下指定的文件,或者该文件夹下所有文件
     *
     * @param fp
     * @param remotePathName  远程文件   服务器地址
     * @param localPathName   本地文件   客户端
     * @param fileName        下载的文件名
     * @return
     */
    public static boolean downLoadFile(final FtpParamter fp, final String remotePathName, final String localPathName, final String fileName) {
        // 登录
        if(!loginFtp(fp)) {
            return false;
        }
        boolean flag = true;
        boolean changedir;
        OutputStream os = null;
        try {
            ftpclient.enterLocalPassiveMode();
            changedir = ftpclient.changeWorkingDirectory(remotePathName);
            if (!changedir) {
                return false;
            }
            FTPFile[] files = ftpclient.listFiles();
            File localPathFile = new File(localPathName);
            if (!localPathFile.exists() && !localPathFile.isDirectory()) {
                localPathFile.mkdirs();
            }
            for (FTPFile file : files) {
                if (fileName != null) {
                    if (fileName.equals(file.getName())) {
                        os = new FileOutputStream(localPathName + File.separator + file.getName());
                        // 设置传送模式
                        ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
                        // 取得文件
                        flag = ftpclient.retrieveFile(remotePathName + File.separator + file.getName(), os);
                        if (!flag) {
                            break;
                        }
                    }
                } else {
                    os = new FileOutputStream(localPathName + File.separator + file.getName());
                    // 设置传送模式
                    ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
                    // 取得文件
                    flag = ftpclient.retrieveFile(remotePathName + File.separator + file.getName(), os);
                    if (!flag) {
                        break;
                    }
                }
            }
        } catch (Exception e1) {
            flag = false;
            LOGGER.info("downLoadFile Exception", e1.getMessage());
        } finally {
            try {
                if (os != null) {
                    os.flush();
                    os.close();
                }
            } catch (IOException e) {
                LOGGER.error("downLoadFile,FileOutputStream close Exception:", e.getMessage());
            }
            closeFTP();
        }
        return flag;
    }

    /**
     * ftp移动文件到指定目录
     *
     * @param ftpParamter     ftp相关信息对象
     * @param fromFilePath    移动之前文件所在路径
     * @param toFilePath      移动之后文件所在路径
     * @param fromFileName        要移动的文件名
     * @param toFileName          移动之后的文件名
     * @return Boolean
     */
    public static Boolean moveFile(final FtpParamter ftpParamter, final String fromFilePath, final String toFilePath, final String fromFileName, final String toFileName) {
        // 登录
        if(!loginFtp(ftpParamter)) {
            return false;
        }
        try {
            // 3、操作
            Boolean bool2 = ftpclient.makeDirectory(toFilePath);
            LOGGER.info("创建文件夹["+ toFilePath +"]: " + bool2);
            Boolean bool = ftpclient.changeWorkingDirectory(fromFilePath);
            LOGGER.info("改变ftp工作目录[" + fromFilePath + "]: " + bool);
            if(!bool) {
                return false;
            }
            // 3.1: 移动文件到指定目录下
            int RNFRReplayCode = ftpclient.sendCommand(FTPCmd.RNFR, fromFileName);
            int RANTOReplayCode = ftpclient.sendCommand(FTPCmd.RNTO, toFilePath + File.separator + toFileName);
            LOGGER.info("RNFRReplayCode: "+ RNFRReplayCode +", RANTOReplayCode: " + RANTOReplayCode);
            if (!FTPReply.isPositiveIntermediate(RNFRReplayCode) || !FTPReply.isPositiveCompletion(RANTOReplayCode)) {
                return false;
            }
            return true;
        } catch (Exception e) {
            LOGGER.error("移动文件到指定路径出现异常{}", e);
            return false;
        }finally {
            closeFTP();
        }
    }

    /**
     * ftp断开连接
     */
    public static void closeFTP() {
        try {
            ftpclient.disconnect();
        } catch (IOException e) {
            LOGGER.error("retrieveFile,disconnection Exception:" + e.getMessage());
        }
    }
}

一些使用注意

  • 解决ftp阻塞问题

    程序运行到 FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态。
    解决方法:在调用这两个方法之前,调用FTPClient.enterLocalPassiveMode();
    意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。因为ftp server可能每次开启不同的端口来传输数据,但可能在ftp服务运行时,由于安全限制,PC可能某些端口没有开启,所以就出现阻塞。

  • 回退到ftp上一级目录

ftpclient.changeWorkingDirectory("../../");
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值