java通过上传文件至ftp服务器

ftp工具类

import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.function.Function;


/**
 *
 * @author 答案
 */
@Component
public class FtpHelper implements Closeable {
    private final static Logger log = LoggerFactory.getLogger(FtpHelper.class);
    private FTPClient ftp = null;
    boolean _isLogin = false;
    public static FtpHelper getInstance() {
        return new FtpHelper();
    }

    /**
     *
     * ftp 匿名登录
     * @param ip ftp服务地址
     * @param port 端口号
     */
    public boolean login(String ip,int port){
        //如果没有设置ftp用户可将username设为anonymous,密码为任意字符串
        return login(ip, port,"anonymous","");
    }
    /**
     *
     * ftp登录
     * @param ip ftp服务地址
     * @param port 端口号
     * @param uname 用户名
     * @param pass 密码
     */
    public boolean login(String ip,int port, String uname, String pass) {
        ftp = new FTPClient();
//		boolean flag=false;
        try {
            // 连接
            ftp.connect(ip,port);
            _isLogin = ftp.login(uname, pass);
            log.info(_isLogin?"登录成功":"登录失败");
            // 检测连接是否成功
            int reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                System.err.println("FTP服务器拒绝连接 ");
                return false;
            }
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
    /**
     * 上传后触发
     */
    public Function<FtpFileInfo, Boolean> onUploadFileAfter;

    /**
     *
     * ftp上传文件
     * @param localFileName 待上传文件
     * @param ftpDirName ftp 目录名
     * @param ftpFileName ftp目标文件
     * @return true||false
     */
    public boolean uploadFile(String localFileName
            ,String ftpDirName
            , String ftpFileName) {
        return uploadFile(localFileName, ftpDirName, ftpFileName,false);
    }
    /**
     *
     * ftp上传文件
     * @param localFileName 待上传文件
     * @param ftpDirName ftp 目录名
     * @param ftpFileName ftp目标文件
     * @param deleteLocalFile 是否删除本地文件
     * @return true||false
     */
    public boolean uploadFile(String localFileName
            , String ftpDirName
            , String ftpFileName
            , boolean deleteLocalFile) {

        if(StringUtils.isEmpty(ftpFileName))
            throw new RuntimeException("上传文件必须填写文件名!");

        File srcFile = new File(localFileName);
        if(!srcFile.exists())
            throw new RuntimeException("文件不存在:"+localFileName);

        try (FileInputStream fis = new FileInputStream(srcFile)) {
            //上传文件
            boolean flag = uploadFile(fis,ftpDirName,ftpFileName);
            //上传前事件
            if(onUploadFileAfter!=null){
                onUploadFileAfter.apply(new FtpFileInfo(localFileName,ftpDirName,ftpFileName));
            }
            //删除文件
            if(deleteLocalFile){
                srcFile.delete();
                log.info("ftp删除源文件:{0}",srcFile);
            }
            fis.close();
            return flag;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
        }
    }


    /**
     *
     * ftp上传文件 (使用inputstream)
     * @param ftpDirName ftp 目录名
     * @param ftpFileName ftp目标文件
     * @return true||false
     */
    public boolean uploadFile(FileInputStream uploadInputStream
            ,String ftpDirName
            , String ftpFileName) {
        if(StringUtils.isEmpty(ftpFileName))
            throw new RuntimeException("上传文件必须填写文件名!");

        try {
            // 设置上传目录(没有则创建)
            if(!createDir(ftpDirName)){
                throw new RuntimeException("切入FTP目录失败:"+ftpDirName);
            }
            ftp.setBufferSize(1024);
            //解决上传中文 txt 文件乱码
            ftp.setControlEncoding("GBK");
            FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
            conf.setServerLanguageCode("zh");


            // 设置文件类型(二进制)
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            // 上传
            String fileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
            if(ftp.storeFile(fileName, uploadInputStream)){
                uploadInputStream.close();
                log.info("文件上传成功");
                return true;
            }

            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
        }
    }
    /**
     * 下载文件
     * @param ftpDirName ftp目录名
     * @param ftpFileName ftp文件名
     * @param localFileFullName 本地文件名
     * @return
     *  @author xxj
     */
    public boolean downloadFile(String ftpDirName,
                                String ftpFileName, String localFileFullName) {
        try {
            if("".equals(ftpDirName))
                ftpDirName="/";
            String dir = new String(ftpDirName.getBytes("GBK"),"iso-8859-1");
            if(!ftp.changeWorkingDirectory(dir)){
                log.info("切换目录失败:"+ftpDirName);
                return false;
            }
            FTPFile[] fs = ftp.listFiles();
            String fileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    FileOutputStream is = new FileOutputStream(new File(localFileFullName));
                    ftp.retrieveFile(ff.getName(), is);
                    is.close();
                    log.info("下载ftp文件已下载:"+localFileFullName);
                    return true;
                }
            }
            log.info("下载ftp文件失败:"+ftpFileName+";目录:"+ftpDirName);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     *
     * 删除ftp上的文件
     *
     * @param ftpFileName
     * @return true || false
     */
    public boolean removeFile(String ftpFileName) {
        boolean flag ;
        try {
            ftpFileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1");
            flag = ftp.deleteFile(ftpFileName);
            log.info(flag?"成功":"失败");
            return flag;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除空目录
     * @param dir
     * @return
     */
    public boolean removeDir(String dir){
        if(StringUtil.startWith(dir, "/"))
            dir="/"+dir;
        try {
            String d = new String(dir.toString().getBytes("GBK"),"iso-8859-1");
            return ftp.removeDirectory(d);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 创建目录(有则切换目录,没有则创建目录)
     * @param dir
     * @return
     */
    public boolean createDir(String dir){
        if(StringUtils.isEmpty(dir))
            return true;
        String d;
        try {
            //目录编码,解决中文路径问题
            d = new String(dir.toString().getBytes("GBK"),"iso-8859-1");
            //尝试切入目录
            if(ftp.changeWorkingDirectory(d))
                return true;
            dir = StringUtil.trimStart(dir, "/");
            dir = StringUtil.trimEnd(dir, "/");
            String[] arr =  dir.split("/");
            StringBuffer sbfDir=new StringBuffer();
            //循环生成子目录
            for(String s : arr){
                sbfDir.append("/");
                sbfDir.append(s);
                //目录编码,解决中文路径问题
                d = new String(sbfDir.toString().getBytes("GBK"),"iso-8859-1");
                //尝试切入目录
                if(ftp.changeWorkingDirectory(d))
                    continue;
                if(!ftp.makeDirectory(d)){
                    log.info("[失败]ftp创建目录:"+sbfDir.toString());
                    return false;
                }
                log.info("[成功]创建ftp目录:"+sbfDir.toString());
            }
            //将目录切换至指定路径
            return ftp.changeWorkingDirectory(d);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }



    /**
     *
     * 销毁ftp连接
     *
     */
    private void closeFtpConnection() {
        _isLogin = false;
        if (ftp != null) {
            if (ftp.isConnected()) {
                try {
                    ftp.logout();
                    ftp.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     *
     * 销毁ftp连接
     *
     */
    @Override
    public void close() {
        this.closeFtpConnection();
    }

    public static class FtpFileInfo{
        public FtpFileInfo(String srcFile,String ftpDirName,String ftpFileName){
            this.ftpDirName=ftpDirName;
            this.ftpFileName=ftpFileName;
            this.srcFile=srcFile;
        }
        String srcFile;
        String ftpDirName;
        String ftpFileName;
        String ftpFileFullName;

        public String getSrcFile() {
            return srcFile;
        }
        public void setSrcFile(String srcFile) {
            this.srcFile = srcFile;
        }
        public String getFtpDirName() {
            return ftpDirName;
        }
        public void setFtpDirName(String ftpDirName) {
            this.ftpDirName = ftpDirName;
        }
        public String getFtpFileName() {
            return ftpFileName;
        }
        public void setFtpFileName(String ftpFileName) {
            this.ftpFileName = ftpFileName;
        }
        /**
         * 获取ftp上传文件的完整路径名
         * @return
         *  @author xxj
         */
        public String getFtpFileFullName() {
            return StringUtil.Combine("/",ftpDirName,ftpFileName);
        }

    }
}

工具类

public final class StringUtil {


    /**
     * 删除起始字符
     * @param
     * @return
     *  @author xxj 2017年4月27日
     */
    public static String trimStart(String str,String trim){
        if(str==null)
            return null;
        return str.replaceAll("^("+trim+")+", "");
    }

    /**
     * 以字符开头
     * @param s
     * @return
     *  @author xxj 2017年4月27日
     */
    public static boolean startWith(String str,String s){
        return str.startsWith(s);
    }

    /**
     * 删除末尾字符
     * @param
     * @return
     *  @author xxj 2017年4月27日
     */
    public static String trimEnd(String str,String trim){
        if(str==null)
            return null;
        return str.replaceAll("("+trim+")+$", "");
    }

    /**
     * 去空格
     */
    public static String trim(String str)
    {
        return (str == null ? "" : str.trim());
    }

    /**
     * 合并路径
     * @param args
     * @return
     *  @author xxj 2017年4月27日
     */
    public static String Combine(String ...args){
        if(args==null || args.length==0)
            return "";
        StringBuffer sbf = new StringBuffer();
        for(String s:args){
//			//纯协议开头不处理,如:http://,d:/,linux首个/不处理
//			if(s.matches("^[a-zA-z]+://$")){
//				sbf.append(s);
//				continue;
//			}
            //首位地址只删除尾部正反斜杠
            if(sbf.length()==0){
                sbf.append(s.replaceAll("/{1,}$|\\{1,}$", ""));
                continue;
            }

            if(sbf.length()>0)
                sbf.append("/");
            //去除首尾正反斜杠
            sbf.append(s
                    .replaceAll("^/{1,}|^\\{1,}", "")
                    .replaceAll("/{1,}$|\\{1,}$", ""));
        }

        return sbf.toString();
    }

}
    public static File transferToFile(MultipartFile file) throws Exception{
//        选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;

    }

测试

    @CrossOrigin
    @PostMapping("/ftp/uploading")
    public Map<String, Object> ftpImageByCover(MultipartFile file) throws Exception {

        File transferToFile = FileUtil.transferToFile(file);

        //登录ftp服务器,使用用户名 和密码
        ftpHelper.login(host,21,username, password);//改成自己的
        //上传文件
        FileInputStream inputStream = new FileInputStream(transferToFile);

        ftpHelper.uploadFile(inputStream,path,transferToFile.getName());

        return this.getJsonMap();
    }

 

 linux离线安装ftp:CentOS7.9 离线安装FTP服务器_答案的博客-CSDN博客

原文:java-FTPClient-ftp 上传文件、创建目录(支持中文目录、文件名)_草青工作室 的专栏-CSDN博客

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

答 案

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值