Implementar el archivo de descarga ftp a local en Java (detallado)

Realice el archivo de descarga ftp a local en Java (detallado):

2020-09-13: Hoy, grabaré el módulo de funciones que realiza el archivo de descarga ftp a local en Java, y compartiré con ustedes lo que está mal.

1. Protocolo FTP:

¿Qué es FTP? FTP es uno de los protocolos del conjunto de protocolos TCP / IP, que es la abreviatura de English File Transfer Protocol. Este protocolo es la base de la transmisión de archivos de Internet. Está compuesto por una serie de documentos de especificaciones. El objetivo es mejorar el intercambio de archivos, proporcionar un uso indirecto de computadoras remotas y hacer que los medios de almacenamiento sean transparentes para los usuarios y transmitir datos de manera confiable y eficiente. En pocas palabras, FTP es completar la copia entre dos computadoras, copiar archivos desde una computadora remota a su propia computadora, lo que se denomina archivo de "descarga". Si copia un archivo de su propia computadora a una computadora remota, se llama archivo de "carga".

2.Herramientas SSH

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

Lo anterior es una breve introducción al protocolo ftp y algunas herramientas utilizadas. En este artículo, utilicé sftp para descargar en java. La clase utilizada es ChannelSftp . Volvamos al tema y presente mi propia demostración. . . .

Jaja

1. Conectar

 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;
    }

En esta pieza, hemos terminado el primer paso, primero conéctese al control remoto, el código agrega la lógica de reintento (medios de reconexión), puede bajar y comprender algunas de las clases en el código, no voy a tardar mucho- sin aliento ( mi lado Usando ChannelSftp, también podría probar otra clase FtpClient (los grandes pasos son casi los mismos) )

2. Descarga por lotes ( no estaré demasiado aquí , publiqué el código directamente, puedes buscar otras cosas, como eliminar, hay muchas descargas individuales, etc., mi proyecto aquí usa una descarga por lotes, así que publicó un código de párrafo! )

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;
    }

Explique el código a todos

Inserte la descripción de la imagen aquí

La primera oración sftp.cd () es un método que todo el mundo conoce, cd en el directorio ( nota: el punto clave, todos prestan atención: cuando desee operar un determinado archivo de directorio, debe cd a este directorio ( viento, no uno sabe lo mismo ) )

La tercera oración sfpt.ls () es un método, todos lo conocen, verifique el archivo. En el futuro, el código es usar bucles para recorrer los nombres de los archivos en el directorio. Utilizo la colección de listas para guardarlos ( nota: porque quiero obtener el archivo en ese momento, si no es de varios niveles directorio, si no es un directorio de varios niveles , vaya directamente a su lógica Muy bien).

Inserte la descripción de la imagen aquí
¡Qué directorio de varios niveles!

El segundo código

Inserte la descripción de la imagen aquí
Esta sección, como sugiere el nombre, debido a que mi primer código es obtener el nombre de un directorio de varios niveles, luego esta sección es para obtener los archivos en un directorio de varios niveles. Nota: El método cd en el último párrafo del código anterior. Para manipular directorios de varios niveles, cada vez que ingresa a un directorio y luego cambia a otro, debe ingresar una ruta de directorio en cd en el código.

La descarga y el uso compartido de ftp de hoy han terminado, si tienes algo que no entiendes, bienvenido a comentar y te responderé en segundos. ¡Gracias por tu apoyo también! ¡Grabe la vida, grabe el conocimiento! ¡Soy Wang Buzheng !

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/m0_46379371/article/details/108562278
Recomendado
Clasificación