发布时间: 阅读量

FTP服务器做两台机器的文件交互

FTP服务器初始

前言,需求目前有两台服务器,一台用来部署arcgis服务,另一台部署项目,项目这边有长传文件的功能,上传的文件是需要arcgis服务去读取的,但是他们不在一台机器上无法实现读取,所以用到ftp服务器!文件上传项目所在服务器,用ftp相关方法上传到ftp所在服务器的目录,这样arcgis就可以读取上传的文件


话不多说,见代码

1.在pom文件中添加依赖


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

2.FTP工具类

    import lombok.extern.slf4j.Slf4j;
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 java.io.*;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;


/**
 * @author zf1017@foxmail.com
 * @date 2019/7/22 0022 11:34
 * @description
 */
@Slf4j
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();
            if(!ftpClient.isConnected()){
                ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            }

            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                log.info("未连接到FTP,用户名或密码错误。");
                ftpClient.disconnect();
            } else {
                log.info("FTP连接成功。");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            log.info("FTP的IP地址可能错误,请正确配置。");
        } catch (IOException e) {
            e.printStackTrace();
            log.info("FTP的端口错误,请正确配置。");
        }
        return ftpClient;
    }

    /**
     * Title: judgeFtpConnect
     * Description: 判断ftp连接是否成功
     *
     * @param ftpHost
     * @param ftpUserName
     * @param ftpPassword
     * @param ftpPort
     * @return
     */
    public static int judgeFtpConnect(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())) {
                ftpClient.disconnect();
                return 0;
            } else {
                return 1;
            }
        } catch (SocketException e) {
            return 0;
        } catch (IOException e) {
            return 0;
        }
    }

    /**
     * 下载文件
     *
     * @param ftpHost     ftp服务器地址
     * @param ftpUserName anonymous匿名用户登录,不需要密码。administrator指定用户登录
     * @param ftpPassword 指定用户密码
     * @param ftpPort     ftp服务员器端口号
     * @param ftpPath     ftp文件存放物理路径
     * @param fileName    文件路径
     */
    public static String downloadFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
                                      String ftpPath, String localPath, String fileName) {
        String isItDone = "";
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            //ftpClient.setControlEncoding("UTF-8"); // 中文支持
            //ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            //ftpClient.enterLocalPassiveMode();
            //应对中文目录
            ftpPath = new String(ftpPath.getBytes("GBK"),"iso-8859-1");
            ftpClient.changeWorkingDirectory(ftpPath);// 转移到FTP服务器目录
            FTPFile[] fs = ftpClient.listFiles();
            for (FTPFile ff : fs) {
                String fname = new String(ff.getName().getBytes("iso-8859-1"), "gbk");
                if (fname.equals(fileName)) {
                    File newFile = new File(localPath);
                    if(newFile.exists()==false){
                        newFile.mkdirs();
                    }
                    File localFile = new File(localPath + File.separatorChar + fileName);
                    OutputStream os = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(ff.getName(), os);
                    os.close();
                    break;
                }
            }
            ftpClient.logout();
            isItDone = "0";
        } catch (FileNotFoundException e) {
            isItDone = "没有找到" + ftpPath + "文件。";
            e.printStackTrace();
        } catch (SocketException e) {
            isItDone = "连接FTP失败。";
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            isItDone = "文件读取错误。";
            e.printStackTrace();
        }
        return isItDone;
    }

    /**
     * 上传文件
     *
     * @param ftpHost     ftp服务器地址
     * @param ftpUserName anonymous匿名用户登录,不需要密码。administrator指定用户登录
     * @param ftpPassword 指定用户密码
     * @param ftpPort     ftp服务员器端口号
     * @param ftpPath     ftp文件存放物理路径
     * @param fileName    文件路径
     * @param input       文件输入流,即从本地服务器读取文件的IO输入流
     */
    public static String uploadFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
                                    String ftpPath, String fileName, InputStream input) {
        String isItDone = "";
        FTPClient ftp = null;
        try {
            String ftpPaths = new String(ftpPath.getBytes("GBK"), "iso-8859-1");
            ftp = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            if (!ftp.changeWorkingDirectory(ftpPath)) {// 判断目录是否存在,不存在,则创建
                ftp.makeDirectory(ftpPaths);
            }
            ftp.enterLocalPassiveMode();
            ftp.changeWorkingDirectory(ftpPaths);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            fileName = new String(fileName.getBytes("GBK"), "iso-8859-1");
            ftp.storeFile(fileName, input);
            input.close();
            ftp.logout();
            isItDone = "0";
        } catch (UnsupportedEncodingException e) {
            isItDone = "ftp连接错误。";
            e.printStackTrace();
        } catch (IOException e) {
            if (e.getMessage().equals("Connection is not open")) {
                isItDone = "ftp打开连接失败。";
            } else {
                isItDone = "ftp上传错误。";
            }
            e.printStackTrace();
        }
        log.info("success");
        return isItDone;
    }

    public static void createDri(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
                                    String ftpPath) {

        FTPClient ftp = null;
        try {
            String ftpPaths = new String(ftpPath.getBytes("GBK"), "iso-8859-1");
            ftp = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            if (!ftp.changeWorkingDirectory(ftpPath)) {// 判断目录是否存在,不存在,则创建
                ftp.makeDirectory(ftpPaths);
            }
        }catch (Exception e){
            log.error("");
        }
    }


    /**
     * <删除FTP上的文件>
     * <远程删除FTP服务器上的录音文件>
     *
     * @param url        FTP服务器IP地址
     * @param port       FTP服务器端口
     * @param username   FTP服务器登录名
     * @param password   FTP服务器密码
     * @param remotePath 远程文件路径
     * @param fileName   待删除的文件名
     * @return
     * @see [类、类#方法、类#成员]
     */
    public static String deleteFtpFile(String url, int port, String username, String password, String remotePath, String fileName) {
        String success = "";
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            // 连接FTP服务器  
            if (port > -1) {
                ftp.connect(url, port);
            } else {
                ftp.connect(url);
            }
            // 登录  
            ftp.login(username, password);
            ftp.setControlEncoding("GBK");
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            // 转移到FTP服务器目录  
            remotePath = new String(remotePath.getBytes("GBK"), "iso-8859-1");
            ftp.changeWorkingDirectory(remotePath);
            fileName = new String(fileName.getBytes("GBK"), "iso-8859-1");
            boolean isdel = ftp.deleteFile(fileName);
            if (isdel) {
                success = "0";
            } else {
                success = "删除ftp失败";
            }
            ftp.logout();
        } catch (IOException e) {
            success = "删除ftp错误" + e;
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException e) {
                    success = "删除ftp错误" + e;
                }
            }
        }
        return success;
    }




    /**
     * 获取FTP某一特定目录下的所有文件名称
     * @param ftpDirPath    FTP上的目标文件路径
     */
    public static List<String> getFileNameListFromFTP(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, String ftpDirPath) {
        List<String> fileNames = new ArrayList<>();
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            ftpDirPath = new String(ftpDirPath.getBytes("GBK"),"iso-8859-1");
            if (ftpDirPath.startsWith("/") && ftpDirPath.endsWith("/")) {
                // 通过提供的文件路径获取FTPFile对象列表

                FTPFile[] files = ftpClient.listFiles(ftpDirPath);
                // 遍历文件列表,打印出文件名称
                for (int i = 0; i < files.length; i++) {
                    FTPFile ftpFile = files[i];
                    // 此处只打印文件,未遍历子目录(如果需要遍历,加上递归逻辑即可)
                    if (ftpFile.isFile()) {
                        fileNames.add(ftpFile.getName());
                        log.info(ftpDirPath + ftpFile.getName());
                    }
                }
            } else {
                log.error("当前FTP路径不可用");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileNames;
    }

    public static void main(String[] args) throws IOException {
        String ftpHost = "192.168.1.158"; // ftp服务器地址
        int ftpPort = 21;// ftp服务员器端口号
        String ftpUserName = "ceshi";// anonymous匿名用户登录,不需要密码。administrator指定用户登录
        String ftpPassword = "123456";// 指定用户密码
		String ftpPath = "/xxx/"; // ftp文件存放物理路径
		String filePath = "D:/risk/123-测试/"; // 文件路径
		String fileName = "123.zip";// 文件名称

//        List<String> fileNameListFromFTP = FTPUtil.getFileNameListFromFTP(ftpHost, ftpUserName, ftpPassword, ftpPort, "/ftp/risk/input/测试2-97/20190723/");
//        fileNameListFromFTP.forEach(System.out::println);
//		
//		System.out.println(StringUtils.substringAfter("/dsmFile/triggerZip/20180920111722", "/"+".zip"));
//		
        //int a=judgeFtpConnect(ftpHost, ftpUserName, ftpPassword, ftpPort);
        //System.out.println(a);
//		filePath = "d:/log";
//		fileName = "aaa.zip";
//       FTPUtil.downloadFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, filePath, fileName);

//		filePath = "D:\\dsmFile\\emergency\\month";
//		fileName = "月运维汇总2018.07.30-11.55.docx";
		FileInputStream input = new FileInputStream(new File(filePath + File.separatorChar + fileName));
		FTPUtil.uploadFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName, input);

        //System.out.println(FtpUtils.deleteFtpFile(ftpHost, ftpPort, ftpUserName, ftpPassword, "2018年/2018年1月/周运维/大厅使用日志", "aaa.txt"));
//		BigDecimal decimal=new BigDecimal(140);
//		if(new BigDecimal(decimal.intValue()).compareTo(decimal)==0){
//			System.out.println(decimal.toString());
//		}else {
//		System.out.println(decimal.setScale(2,BigDecimal.ROUND_HALF_UP).stripTrailingZeros());}


//		//得到图片缓冲区 
//		BufferedImage bi = new BufferedImage
//
//		(150,70,BufferedImage.TYPE_INT_RGB);//INT精确度达到一定,RGB三原色,高度70,宽度150
//
//		//得到它的绘制环境(这张图片的笔) 
//		Graphics2D g2 = (Graphics2D) bi.getGraphics();
//
//		g2.fillRect(0,0,150,70);//填充一个矩形 左上角坐标(0,0),宽70,高150;填充整张图片 
//		//设置颜色 
//		g2.setColor(Color.WHITE); 
//		g2.fillRect(0,0,150,70);//填充整张图片(其实就是设置背景颜色)
//
//		g2.setColor(Color.RED); 
//		g2.drawRect(0,0,150-1,70-1); //画边框
//
//		g2.setFont(new Font("宋体",Font.BOLD,18)); //设置字体:字体、字号、大小 
//		g2.setColor(Color.BLACK);//设置背景颜色
//		g2.drawString("Ⅳ",3,50); //向图片上写字符串 
//		
//
//		ImageIO.write(bi,"JPEG",new FileOutputStream("F:/a.jpg"));//保存图片 JPEG表示保存格式
    }


}

使用过程中遇到两个问题

1.一个是中文目录读取不到,原因是因为编码问题

//解决办法就是在对传入的路径进行编码
 String ftpPaths = new String(ftpPath.getBytes("GBK"), "iso-8859-1");

2.第二个问题是因为ftp服务连接数不够,代码中没有做限制,每请求一次方法就连接一次,导致报连接的服务器端口错误,也是很奇怪报这个错误

//解决办法,连接服务器之前先判断是否连接
 if(!ftpClient.isConnected()){
                ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            }

wei-xin-tu-pian-_20190729164450

安装的时候把必要的信息填写全,要注意的就是路径,比如说我这边是D:\DevelopTools\ftp
生成的文件就是相对这个目录的

wei-xin-tu-pian-_20190729164659


后续,总的来说,很快的解决了我们的需求,使用起来也很方便!