Implement ftp download file to local in Java (detailed)

Realize ftp download file to local in Java (detailed):

2020-09-13: Today, I will record the function module that realizes ftp download file to local in java, and share with you what is wrong. You can point out!

1. FTP protocol:

What is FTP? FTP is one of the protocols in the TCP/IP protocol suite, which is the abbreviation of English File Transfer Protocol. This protocol is the basis of Internet file transfer. It consists of a series of specification documents. The goal is to improve file sharing, provide indirect use of remote computers, and make storage media transparent to users and transfer data reliably and efficiently. Simply put, FTP is to complete the copy between two computers, copy files from a remote computer to your own computer, which is called a "download" file. If you copy a file from your own computer to a remote computer, it is called an "upload" file.

2.SSH tools

ssh---ftp----winscp----filezilla-----xftp----

The above is a brief introduction to the ftp protocol and some tools used. In this article, I used sftp to download in java. The class used is ChannelSftp . Let’s get back to the subject and present my own demo. . . .

Ha ha

1. Connect

 protected static Logger log = LoggerFactory.getLogger(FTPUtil.class);

    public static final String NO_FILE = "No such file";

    private ChannelSftp sftp = null;

    private Session sshSession = null;

    /* FTP账号 */
    private String username;
    /* FTP密码 */
    private String password;
    /* FTP主机 */
    private String host;
    /* FTP端口 */
    private int port;

    public FTPUtil(String host, int port, String username, String password) {
    
    
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    /**
     * 连接sftp服务器
     *
     * @return ChannelSftp sftp类型
     * @throws Exception
     */
    public ChannelSftp connect() throws FtpException {
    
    
        log.info("尝试连接FTP {host=" + host + ",username=" + username + ",port=" + port + "}");
        boolean connect = false;
        JSch jsch = new JSch();
        try {
    
    
            int tryCountAll = 5;
            int tryCount = 0;
            while (tryCount++ < tryCountAll && !connect) {
    
    
                if (tryCount > 1) {
    
    
                    try {
    
    
                        Thread.sleep(5000 * (tryCount - 1));
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                    log.info("第" + tryCount + "次尝试连接FTP服务器");
                }
                sshSession = jsch.getSession(username, host, port);
                sshSession.setPassword(password);
                Properties properties = new Properties();
                properties.put("StrictHostKeyChecking", "no");
                sshSession.setConfig(properties);
                sshSession.connect(50000);
                Channel channel = sshSession.openChannel("sftp");
                channel.connect(50000);
                sftp = (ChannelSftp) channel;
                if (sftp == null) {
    
    
                    log.info("FTP 服务器未连接");
                    connect = false;
                } else {
    
    
                    log.info("连接 FTP 成功!");
                    connect = true;
                }
            }
        } catch (JSchException e) {
    
    
            throw new FtpException("连接 FTP 异常 : " + e.getMessage());
        }
        return sftp;
    }

In this piece, we have finished the first step, first connect to the remote, the code adds the logic of retry (reconnection means), you can go down and understand some of the classes in the code, I will not be too long-winded ( my side Using ChannelSftp, you might as well try another FtpClient class (the big steps are almost the same) )

2. Batch download ( I won’t be too much here , I posted the code directly, you can search for other things, such as delete, there are many single downloads, etc., my project here uses a batch download, so I posted a paragraph Code! )

public void createDirectoryQuietly(File file) {
    
    
        if (file != null) {
    
    
            if (!file.exists()) {
    
    
                if (!file.mkdirs()) {
    
    
                    throw new RuntimeException(file.getName() + " is invalid,can't be create directory");
                }
            }
        }
    }

	//remoteDir 是FTP上要下载的目录
	// localFile 是下载的本地目录
    public File downloadFileNew(String remoteDir, String localFile) throws FtpException {
    
    
        long startTime = System.currentTimeMillis();
        connect();  //连接ftp
        log.info("开始下载文件FTP目录 " + remoteDir + " 本地文件 " + localFile);
        File file = null;
        file = new File(localFile);
       /* if (file.exists()) {

            deleteFileAll(file);
        }
        file.mkdirs();*/
        createDirectoryQuietly(file);//创建目录文件,(这个方法可以创建目录,但多层级的我没试,大家定义路径的时候可以 /home/test  home是本来就有的test会创建)
        OutputStream output = null;
        try {
    
    

            /***
             * 得到custInfo路径下所有文件名
             */
            sftp.cd(remoteDir);  //进入remoteDir目录
            String path = remoteDir + "/custInfo";
            Vector v = sftp.ls(path);   //获取custInfo下文件列表
            List<String> filenameNew = new ArrayList<>(); //获取custInfo下所有目录文件名
            if (v.size() > 0) {
    
    
                log.info("文件个数不为0,开始下载。。。。。。。。。filesize=" + v.size());
                Iterator it = v.iterator();
                while (it.hasNext()) {
    
       //循环文件
                    ChannelSftp.LsEntry lsentry = (ChannelSftp.LsEntry) it.next();
                    String filenames = lsentry.getFilename();
                    if (!".".equals(filenames) && !"..".equals(filenames)) {
    
    
                        log.info(path + "路径下的文件名" + filenames);
                        filenameNew.add(filenames);
                    }
                }
            } else {
    
    
                log.info("获取文件失败 " + remoteDir + "文件数为0");
                throw new FtpException("获取文件失败 " + remoteDir + "文件数为0");
            }

            /***
             * 得到custInfo/路径下各个文件下的文件名
             */
            sftp.cd(path);  //切换到custInfo/路径下
            for (int i = 0; i < filenameNew.size(); i++) {
    
      //得到每个目录文件下的文件
                System.out.println(filenameNew.get(i) + "文件名");
                Vector<?> vNew = sftp.ls(filenameNew.get(i));  //获取文件列表
                sftp.cd(filenameNew.get(i)); //切换到custInfo/路径下各个文件路径下
                File file2=new File(localFile+"/"+filenameNew.get(i));
                if (file2.exists()) {
    
    
                    file2.delete();
                }
                file2.mkdir();
                if (vNew.size() > 0) {
    
    
                    Iterator it = vNew.iterator();
                    while (it.hasNext()) {
    
    
                        ChannelSftp.LsEntry lsentry = (ChannelSftp.LsEntry) it.next();
                        String filenames1 = lsentry.getFilename();
                        if (!".".equals(filenames1) && !"..".equals(filenames1)) {
    
    
                            log.info(filenameNew.get(i) + "路径下的文件名" + filenames1);
                            File file1 = new File(file2+"/"+filenames1);
                            file1.createNewFile();
                            output = new FileOutputStream(file1);
                            sftp.get(filenames1, output);
                            log.info("文件:" + filenames1 + " 下载成功.");
                        }
                    }
                    sftp.cd(path);  //每次路径下载后再切换到 上一级目录
                }
            }
        } catch (SftpException e) {
    
    
            if (e.toString().equals(NO_FILE)) {
    
    
                log.info("下载文件失败");
                throw new FtpException("下载文件失败");
            }
            throw new FtpException("ftp目录或者文件异常,检查ftp目录和文件" + e.toString());
        } catch (FileNotFoundException e) {
    
    
            throw new FtpException("本地目录异常,请检查" + file.getPath() + e.getMessage());
        } catch (IOException e) {
    
    
            throw new FtpException("创建本地文件失败" + file.getPath() + e.getMessage());
        } finally {
    
    
            if (output != null) {
    
    
                try {
    
    
                    output.close();
                } catch (IOException e) {
    
    
                    throw new FtpException("Close stream error." + e.getMessage());
                }
            }
            disconnect();
        }
        log.info("下载文件结束 耗时:" + (System.currentTimeMillis() - startTime) + " ms");
        return file;
    }

Explain the code to everyone

Insert picture description here

The first sentence sftp.cd() is a method that everyone knows, cd into the directory ( note: the key point, everyone pays attention: when you want to operate a certain directory file, you must cd to this directory ( windy, no one knows the same ) )

The third sentence sfpt.ls() is a method, everyone knows it, check the file. In the future, the code is to use loops to loop out the file names in the directory. I use the list collection to save them ( note: because I want to get the file at the time, if it is not a multi- level directory, if you are not a multi- level directory , go straight to your logic Just fine.)

Insert picture description here
Such a multi-level directory!

The second code

Insert picture description here
This section, as the name suggests, because my first code is to get the name of a multi-level directory, then this section is to get the files in a multi-level directory. Note: The cd method in the last paragraph of the above code. To manipulate multi-level directories, every time you enter a directory and then change to another, you have to enter a directory path under cd in the code!

Today’s ftp download and share is over, if you have anything you don’t understand, welcome to comment and I will reply in seconds! Thank you for your support too! Record life, record knowledge! I am Wang Buzheng !

Insert picture description here

Guess you like

Origin blog.csdn.net/m0_46379371/article/details/108562278