FTP上传下载工具类 —— FtpUtils

依赖包:

<dependency>
	<groupId>commons-netgroupId>
	<artifactId>commons-netartifactId>
	<version>3.3version>
dependency>

FtpUtils:

@Slf4j
public class FtpUtils {

    /**
     * Connect to FTP server.
     *
     * @param host FTP server address or name, port, user name, user password
     * @throws IOException on I/O errors
     */
    private static boolean connect(FTPClient ftpClient, Host host) throws IOException {
        if (ftpClient == null) {
            return false;
        }

        // Connect to server.
        try {
            // 解决上传文件时文件名乱码
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.connect(host.getHost(), host.getPort());
        } catch (IOException ex) {
            throw new IOException("Can't find FTP server '" + host.getHost() + "'");
        }

        // Check rsponse after connection attempt.
        int reply = ftpClient.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            disconnect(ftpClient);
            throw new IOException("Can't connect to server '" + host.getHost() + "'");
        }

        // Login.
        if (!ftpClient.login(host.getUserName(), host.getPassword())) {
            disconnect(ftpClient);
            throw new IOException("Can't login to server '" + host.getHost() + "'");
        }

        // Set data transfer mode.
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        //ftp.setFileType(FTP.ASCII_FILE_TYPE);

        // Use passive mode to pass firewalls.
        ftpClient.enterLocalPassiveMode();

        return true;
    }

    /**c
     * Disconnect from the FTP server
     *
     * @throws IOException on I/O errors
     */
    private static void disconnect(FTPClient ftpClient) throws IOException {
        if (ftpClient != null && ftpClient.isConnected()) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (IOException ignored) {
            }
        }
    }

    /**
     * Get file from ftp server into given output stream
     *
     * @param ftpFileName file name on ftp server
     * @param out         OutputStream
     * @throws IOException
     */
    public static void retrieveFile(Host host, String ftpFileName, OutputStream out) throws IOException {
        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            connect(ftpClient, host);
            // Get file info.
            FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
            if (fileInfoArray == null || fileInfoArray.length == 0) {
                throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server.");
            }

            // Check file size.
            FTPFile fileInfo = fileInfoArray[0];
            long size = fileInfo.getSize();
            if (size > Integer.MAX_VALUE) {
                throw new IOException("File '" + ftpFileName + "' is too large.");
            }

            // Download file.
            if (!ftpClient.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file '" + ftpFileName + "' from FTP server. Check FTP permissions and path.");
            }

            out.flush();

        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException ignored) {
            }
            disconnect(ftpClient);
        }
    }

    public static InputStream retrieveFile(Host host, String ftpFileName) throws IOException {
        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);

        // Get file info.
        FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
        if (fileInfoArray == null || fileInfoArray.length == 0) {
            throw new FileNotFoundException("File '" + ftpFileName + "' was not found on FTP server.");
        }

        // Check file size.
        FTPFile fileInfo = fileInfoArray[0];
        long size = fileInfo.getSize();
        if (size > Integer.MAX_VALUE) {
            throw new IOException("File '" + ftpFileName + "' is too large.");
        }

        // get InputStream
        InputStream inputStream = ftpClient.retrieveFileStream(ftpFileName);
        disconnect(ftpClient);
        return inputStream;
    }

    /**
     * Put file on ftp server from given input stream
     *
     * @param ftpFileName file name on ftp server
     * @param in          InputStream
     * @throws IOException
     */
    public static boolean storeFile(Host host, String path, String ftpFileName, InputStream in) throws IOException {
        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            connect(ftpClient, host);

            createDirectory(ftpClient, path);
            if (!ftpClient.storeFile(ftpFileName, in)) {
                throw new IOException("Can't upload file '" + ftpFileName + "' to FTP server. Check FTP permissions and path.");
            }

            return true;
        } finally {
            try {
                in.close();
            } catch (IOException ignored) {
            }
            disconnect(ftpClient);
        }
    }

    /**
     * Delete the file from the FTP server.
     *
     * @param ftpFileName server file name (with absolute path)
     * @throws IOException on I/O errors
     */
    public void deleteFile(Host host, String ftpFileName) throws IOException {
        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);
        if (!ftpClient.deleteFile(ftpFileName)) {
            throw new IOException("Can't remove file '" + ftpFileName + "' from FTP server.");
        }

        disconnect(ftpClient);
    }

    /**
     * Upload the file to the FTP server.
     *
     * @param remotePath server file name (with absolute path)
     * @param localFile  local file to upload
     * @throws IOException on I/O errors
     */
    public static void upload(Host host, String remotePath, String fileName, File localFile) throws IOException {
        // File check.
        if (!localFile.exists()) {
            throw new IOException("Can't upload '" + localFile.getAbsolutePath() + "'. This file doesn't exist.");
        }

        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);

        // Upload.
        try (InputStream in = new BufferedInputStream(new FileInputStream(localFile))) {
            createDirectory(ftpClient, remotePath);
            if (!ftpClient.storeFile(fileName, in)) {
                throw new IOException("Can't upload file '" + remotePath + "' to FTP server. Check FTP permissions and path.");
            }
        }

        disconnect(ftpClient);
    }

    private static void createDirectory(FTPClient ftpClient, String remote) throws IOException {
        String directory = remote + "/";
        if ("/".equalsIgnoreCase(directory) || ftpClient.changeWorkingDirectory(directory)) {
            return;
        }

        // 如果远程目录不存在,则递归创建远程服务器目录
        int start;
        int end;
        if (directory.startsWith("/")) {
            start = 1;
        } else {
            start = 0;
        }
        end = directory.indexOf("/", start);
        String path = "";
        do {
            String subDirectory = remote.substring(start, end);
            path = path + "/" + subDirectory;

            // 不存在 -> 创建
            if (!existFile(ftpClient, path) && !makeDirectory(ftpClient, subDirectory)) {
                log.debug("创建目录[" + subDirectory + "]失败");
            }
            ftpClient.changeWorkingDirectory(subDirectory);

            start = end + 1;
            end = directory.indexOf("/", start);
            // 检查所有目录是否创建完毕
        } while (end > start);
    }

    /**
     * 判断ftp服务器文件是否存在
     *
     * @param path 路径
     * @return 是否存在
     */
    private static boolean existFile(FTPClient ftpClient, String path) throws IOException {
        return ftpClient.listFiles(path).length > 0;
    }

    /**
     * 创建目录
     *
     * @param dir
     * @return
     */
    private static boolean makeDirectory(FTPClient ftpClient, String dir) {
        boolean flag = true;
        try {
            flag = ftpClient.makeDirectory(dir);
            if (flag) {
                log.debug("创建文件夹" + dir + " 成功!");
            } else {
                log.debug("创建文件夹" + dir + " 失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * Download the file from the FTP server.
     *
     * @param ftpFileName server file name (with absolute path)
     * @param localFile   local file to download into
     * @throws IOException on I/O errors
     */
    public static void download(Host host, String ftpFileName, File localFile) throws IOException {
        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);

        // Download.
        // Get file info.
        FTPFile[] fileInfoArray = ftpClient.listFiles(ftpFileName);
        if (fileInfoArray == null || fileInfoArray.length == 0) {
            throw new FileNotFoundException("File " + ftpFileName + " was not found on FTP server.");
        }

        // Check file size.
        FTPFile fileInfo = fileInfoArray[0];
        long size = fileInfo.getSize();
        if (size > Integer.MAX_VALUE) {
            throw new IOException("File " + ftpFileName + " is too large.");
        }

        try (OutputStream out = new BufferedOutputStream(new FileOutputStream(localFile))) {
            // Download file.
            if (!ftpClient.retrieveFile(ftpFileName, out)) {
                throw new IOException("Error loading file " + ftpFileName + " from FTP server. Check FTP permissions and path.");
            }

            out.flush();
        } finally {
            disconnect(ftpClient);
        }
    }

    /**
     * List the file name in the given FTP directory.
     *
     * @param filePath absolute path on the server
     * @return files relative names list
     * @throws IOException on I/O errors
     */
    public List<String> listFileNames(Host host, String filePath) throws IOException {
        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);

        List<String> fileList = new ArrayList<>();
        FTPFile[] ftpFiles = ftpClient.listFiles(filePath);
        for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
            FTPFile ftpFile = ftpFiles[i];
            if (ftpFile.isFile()) {
                fileList.add(ftpFile.getName());
            }
        }

        disconnect(ftpClient);
        return fileList;
    }

    /**
     * List the files in the given FTP directory.
     *
     * @param filePath directory
     * @return list
     * @throws IOException
     */
    public List<FTPFile> listFiles(Host host, String filePath) throws IOException {
        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);

        List<FTPFile> fileList = new ArrayList<>();
        FTPFile[] ftpFiles = ftpClient.listFiles(filePath);
        for (int i = 0; ftpFiles != null && i < ftpFiles.length; i++) {
            FTPFile ftpFile = ftpFiles[i];
            fileList.add(ftpFile);
        }

        disconnect(ftpClient);
        return fileList;
    }


    /**
     * Send an FTP Server site specific command
     *
     * @param args site command arguments
     * @throws IOException on I/O errors
     */
    public void sendSiteCommand(Host host, String args) throws IOException {
        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);
        if (!ftpClient.isConnected()) {
            return;
        }

        try {
            ftpClient.sendSiteCommand(args);
        } finally {
            disconnect(ftpClient);
        }
    }

    /**
     * Get current directory on ftp server
     *
     * @return current directory
     */
    public String printWorkingDirectory(Host host) throws IOException {
        FTPClient ftpClient = new FTPClient();
        connect(ftpClient, host);
        if (!ftpClient.isConnected()) {
            return "";
        }

        try {
            return ftpClient.printWorkingDirectory();
        } finally {
            disconnect(ftpClient);
        }
    }

    public static class Host {
        private String host;
        private int port;
        private String userName;
        private String password;

        public Host(String host, int port, String userName, String password) {
            this.host = host;
            this.port = port;
            this.userName = userName;
            this.password = password;
        }

        public String getHost() {
            return host;
        }

        public void setHost(String host) {
            this.host = host;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    public static void main(String[] args) throws Exception {
        Host host = new Host("192.168.200.13", 21, "test", "test@123");
        FtpUtils.retrieveFile(host, "/baseinfo/杭州/人员信息/QQ截图20200722144326.png");

        File file = new File("C:/Users/epsoft/Desktop/QQ截图20200722144326.png");
        FtpUtils.storeFile(host, "/baseinfo/杭州/人员信息", "QQ截图20200722144326.png", new FileInputStream(file));
    }
}

你可能感兴趣的:(Utils,ftp,java)