SimpleFTPClient


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Base64;
import java.util.LinkedList;
import java.util.List;


import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
<!--apacheftp-->
<!--导入commons-net依赖-->
<!--https://mvnrepository.com/artifact/commons-net/commons-net-->
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.6</version>
</dependency>

<!-- 引入Apache的commons-lang3包,方便操作字符串-->
<!--https://mvnrepository.com/artifact/org.apache.commons/commons-lang3-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8</version>

</dependency>

<!--引入Apachecommons-io包,方便操作文件-->
<!--https://mvnrepository.com/artifact/commons-io/commons-io-->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
*/

public class SimpleFTPClient {
    private static final Logger logger = LoggerFactory.getLogger(SimpleFTPClient.class);
    private static FTPClient connectFtpServer(String url,String userName,String password){

        String  str = url.replaceFirst("ftp://", "").replaceFirst("FTP://", "");
        str=str.replaceAll("/+", "/");
        int endIndex = str.indexOf("/");
        str = str.substring(0,endIndex);
        url = str;//"ftp://"+str+"/";

        String[] addr = url.split(":");
        FTPClient ftpClient = new FTPClient();
        ftpClient.setConnectTimeout(1000*5);//设置连接超时时间
        // ftpClient.setControlEncoding("GBK");   
        ftpClient.setControlEncoding("utf-8");//设置ftp字符集
        ftpClient.enterLocalPassiveMode();//设置被动模式,文件传输端口设置
        try {
           
            ftpClient.connect(addr[0],Integer.parseInt(addr[1]));
           
            if(null==userName||"".equals(userName)){
                userName = "anonymous";
                password = "password";
            }
            boolean isLoginSuccess = ftpClient.login(userName,password);
            logger.info("isLoginSuccess="+isLoginSuccess);

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置文件传输模式为二进制,可以保证传输的内容不会被改变

            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)){
                logger.error("connect ftp {} failed",url);
                ftpClient.abort();
                ftpClient.disconnect();
                return null;
            }
            logger.info("replyCode==========={}",replyCode);
        } catch (IOException e) {
            logger.error("connect fail ------->>>{}",e);
            return null;
        }
        return ftpClient;
}
    /**
     *
     * @param inputStream 待上传文件的输入流
     * @param originName 文件保存时的名字
     */
    public void uploadFile(String url,String userName,String password,InputStream inputStream, String originName){
        FTPClient ftpClient = connectFtpServer(url,userName,password);
        if (ftpClient == null){
            return;
        }
       
        /* try {
            ftpClient.changeWorkingDirectory(remoteDir);//进入到文件保存的目录
            Boolean isSuccess = ftpClient.storeFile(originName,inputStream);//保存文件
            if (!isSuccess){
                throw new BusinessException(ResponseCode.UPLOAD_FILE_FAIL_CODE,originName+"---》上传失败!");
            }
            logger.info("{}---》上传成功!",originName);
            ftpClient.logout();
        } catch (IOException e) {
            logger.error("{}---》上传失败!",originName);
            throw new BusinessException(ResponseCode.UPLOAD_FILE_FAIL_CODE,originName+"上传失败!");
        }finally {
            if (ftpClient.isConnected()){
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error("disconnect fail ------->>>{}",e.getCause());
                }
            }
        } */
    }
/**
     *  读ftp上的文件,并将其转换成base64
     * @param remoteFileName ftp服务器上的文件名
     * @return
     */
    public static String readFileToBase64(String url,String userName,String password){
        logger.info("url={}",url);
        FTPClient ftpClient = connectFtpServer(url,userName,password);
        if (ftpClient == null){
            return null;
        }
        logger.info("ftpClient={}",ftpClient.isAvailable()&&ftpClient.isConnected());
        String base64 = "";
        InputStream inputStream = null;
        ByteArrayOutputStream os=null;
        String remoteDir;
        String  str = url.replaceFirst("ftp://", "").replaceFirst("FTP://", "");
        str=str.replaceAll("/+", "/");
        int beginIndex = str.indexOf("/");
        int endIndex = str.lastIndexOf("/");
        remoteDir=str.substring(beginIndex,endIndex+1);
        logger.info("remoteDir={}",remoteDir);
        String remoteFileName = str.substring(endIndex+1);
        logger.info("remoteFileName={}",remoteFileName);
        try {
            boolean chDirRes = ftpClient.changeWorkingDirectory(remoteDir);
            logger.info("changeWorkingDirectory={}",chDirRes);
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles(remoteDir);
            logger.info("ftpFiles.length={}",ftpFiles.length);
            Boolean flag = false;
            //遍历当前目录下的文件,判断要读取的文件是否在当前目录下
            for (FTPFile ftpFile:ftpFiles){
                if (ftpFile.getName().equals(remoteFileName)){
                    flag = true;
                    break;
                }
            }

            if (!flag){
                logger.error("directory:{}下没有 {}",remoteDir,remoteFileName);
                return null;
            }

           /*  // 下载ftp上指定文件到本地
            File localFile = new File("D:" + File.separator +"abc_"+ remoteFileName);
            boolean downloaded = ftpClient.retrieveFile(remoteFileName,
            new FileOutputStream(localFile));
           
            System.out.println(ftpClient.getReplyString()); */




            logger.info("开始获取文件流");
            //获取待读文件输入流
            inputStream = ftpClient.retrieveFileStream(remoteFileName); // remoteDir+remoteFileName

            // //inputStream.available() 获取返回在不阻塞的情况下能读取的字节数,正常情况是文件的大小
            logger.info("完成获取文件流");
            byte[] bytes = new byte[1024];
            os = new ByteArrayOutputStream();
            int len=-1;
            while( (len=inputStream.read(bytes))!=-1){//将文件数据读到字节数组中
                os.write(bytes, 0, len);
            }
            os.flush();
            byte[] fileBytes = os.toByteArray();
          
            /* File file = new File("d:/"+remoteFileName);
            OutputStream fos = new FileOutputStream(file);
            try {
                fos.write(fileBytes);
                fos.flush();
            } catch (Exception e) {
                //TODO: handle exception
            }
           finally{
            fos.close();
           } */
            

            int fileSize = fileBytes.length;
            logger.info("fileSize={}",fileSize);
            Base64.Encoder encoder = Base64.getEncoder();
            base64 = encoder.encodeToString(fileBytes);
            logger.debug("base64 img="+base64);
            logger.info("read file {} success",remoteFileName);

            if(!ftpClient.completePendingCommand()) {
                ftpClient.logout();
                ftpClient.disconnect();
                   logger.error("File transfer failed.");
                   return null;
            }

            ftpClient.logout();
        } catch (IOException e) {
            logger.error("read file fail ----->>>{}",e.getCause());
            return null;
        }finally {
            if (ftpClient.isConnected()){
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error("disconnect fail ------->>>{}",e.getCause());
                }
            }

            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    logger.error("inputStream close fail -------- {}",e.getCause());
                }
            }

            if (os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    logger.error("os close fail -------- {}",e.getCause());
                }
            }

        }

        return base64;

 }
/**
     * 文件下载
     * @param remoteFileName ftp上的文件名
     * @param localFileName 本地文件名
     */
    public void download(String url,String userName,String password,String remoteFileName,String localFileName){
        FTPClient ftpClient = connectFtpServer(url,userName,password);
        if (ftpClient == null){
            return ;
        }

        OutputStream outputStream = null;

        /* try {
            ftpClient.changeWorkingDirectory(remoteDir);
            FTPFile[] ftpFiles = ftpClient.listFiles(remoteDir);
            Boolean flag = false;
            //遍历当前目录下的文件,判断是否存在待下载的文件
            for (FTPFile ftpFile:ftpFiles){
                if (ftpFile.getName().equals(remoteFileName)){
                    flag = true;
                    break;
                }
            }

            if (!flag){
                logger.error("directory:{}下没有 {}",remoteDir,remoteFileName);
                return ;
            }

            outputStream = new FileOutputStream(localDir+localFileName);//创建文件输出流

            Boolean isSuccess = ftpClient.retrieveFile(remoteFileName,outputStream); //下载文件
            if (!isSuccess){
                logger.error("download file 【{}】 fail",remoteFileName);
            }

            logger.info("download file success");
            ftpClient.logout();
        } catch (IOException e) {
            logger.error("download file 【{}】 fail ------->>>{}",remoteFileName,e.getCause());
        }finally {
            if (ftpClient.isConnected()){
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error("disconnect fail ------->>>{}",e.getCause());
                }
            }

            if (outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    logger.error("outputStream close fail ------->>>{}",e.getCause());
                }
            }
        } */
    }

    public static void main(String[] args) {
        // String ftpPath = "ftp://192.168.1.3:8010/recordsImg/2019-05-31/STRANGERBABY_1559265983072.jpg";
        // readFileToBase64(ftpPath,"","");
        String url="ftp://106.12.195.197:21/";
        FTPClient ftpClient = connectFtpServer(url,"myftp","123456");
        if (ftpClient == null){
            return ;
        }
        logger.info("ftpClient={}",ftpClient.isAvailable()&&ftpClient.isConnected());
        String base64 = "";
        InputStream inputStream = null;
        ByteArrayOutputStream os=null;
        String remoteDir;
        String  str = url.replaceFirst("ftp://", "").replaceFirst("FTP://", "");
        str=str.replaceAll("/+", "/");
        int beginIndex = str.indexOf("/");
        // int endIndex = str.lastIndexOf("/");
        
        // remoteDir=str.substring(beginIndex,endIndex+1);
        String remotePath =str.substring(beginIndex);
        logger.info("remotePath={}",remotePath);
        String status="nil";
        try {
            status=ftpClient.getStatus(remotePath);
        } catch (Exception e) {
            //TODO: handle exception
            e.printStackTrace();
        }
        logger.info("ftpClient.getStatus={}",status);
    
        try {
            // boolean chDirRes = ftpClient.changeWorkingDirectory(remoteDir);
            // logger.info("changeWorkingDirectory={}",chDirRes);
            // ftpClient.enterLocalPassiveMode();
           /*  FTPFile[] ftpFiles = ftpClient.listFiles(remoteDir);
            logger.info("ftpFiles.length={}",ftpFiles.length);
            Boolean flag = false;
            //遍历当前目录下的文件,判断要读取的文件是否在当前目录下
            for (FTPFile ftpFile:ftpFiles){
                logger.info("ftpFiles------{}",ftpFile.getName());
            } */
        //    boolean renameRes = ftpClient.rename("/imgfacebak/bb1.png", "/test/a.png");
        //    logger.info("renameRes={}",renameRes);
            // if(!ftpClient.completePendingCommand()) {
            //     ftpClient.logout();
            //     ftpClient.disconnect();
            //        logger.error("File transfer failed.");
            //        return ;
            // }

            ftpClient.logout();
          
        } catch (IOException e) {
            logger.error("read file fail ----->>>{}",e.getCause());
            return ;
        }finally {
            if (ftpClient.isConnected()){
                try {
                    ftpClient.disconnect();
                } catch (IOException e) {
                    logger.error("disconnect fail ------->>>{}",e.getCause());
                }
            }

            

        }

       




    }

}