zoukankan      html  css  js  c++  java
  • JAVA FTP/SFTP 上传下载文件

    1.FTP 工具类

    package com.example.demo.utlis;
    
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.*;
    import java.net.SocketException;
    
    public class FtpUtil2 {
    
        private static FTPClient ftpClient = new FTPClient();
    
        /**
         * 获取FTPClient对象
         *
         * @param ftpHost     FTP主机服务器
         * @param ftpPassword FTP 登录密码
         * @param ftpUserName FTP登录用户名
         * @param ftpPort     FTP端口 默认为21
         * @return
         */
        public FTPClient getFTPClient(String ftpHost, String ftpUserName,
                                      String ftpPassword, int ftpPort) {
    
            try {
    
                ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
                ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
                if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                    System.out.println("未连接到FTP,用户名或密码错误。");
                    ftpClient.disconnect();
                } else {
                    System.out.println("FTP连接成功。");
                }
            } catch (SocketException e) {
                e.printStackTrace();
                System.out.println("FTP的IP地址可能错误,请正确配置。");
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("FTP的端口错误,请正确配置。");
            }
            return ftpClient;
        }
    
    
        /**
         * 从FTP服务器下载文件
         *
         * @param ftpPath   FTP服务器中文件所在路径
         * @param localPath 下载到本地的位置
         * @param fileName  文件名称
         */
        public void downloadFtpFile(String ftpPath, String localPath,
                                    String fileName) {
            try {
    
                ftpClient.setControlEncoding("UTF-8"); // 中文支持
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.enterLocalPassiveMode();
                ftpClient.changeWorkingDirectory(ftpPath);
    
                File localFile = new File(localPath + File.separatorChar + fileName);
                OutputStream os = new FileOutputStream(localFile);
                ftpClient.retrieveFile(fileName, os);
                os.close();
                ftpClient.logout();
    
            } catch (FileNotFoundException e) {
                System.out.println("没有找到" + ftpPath + "文件");
                e.printStackTrace();
            } catch (SocketException e) {
                System.out.println("连接FTP失败.");
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("文件读取错误。");
                e.printStackTrace();
            }
    
        }
    
        /**
         * Description: 向FTP服务器上传文件
         *
         * @param ftpPath  FTP服务器中文件所在路径 格式: ftptest/aa
         * @param fileName ftp文件名称
         * @param input    文件流
         * @return 成功返回true,否则返回false
         */
        public boolean uploadFile(String ftpPath,
                                  String fileName, InputStream input) {
            boolean success = false;
    
            try {
                int reply;
    
                reply = ftpClient.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftpClient.disconnect();
                    return success;
                }
                ftpClient.setControlEncoding("UTF-8"); // 中文支持
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                ftpClient.enterLocalPassiveMode();
                ftpClient.changeWorkingDirectory(ftpPath);
    
                ftpClient.storeFile(fileName, input);
    
                input.close();
                ftpClient.logout();
                success = true;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ftpClient.isConnected()) {
                    try {
                        ftpClient.disconnect();
                    } catch (IOException ioe) {
                    }
                }
            }
            return success;
        }
    
    
        public static void main(String args[]) {
    
            String ftpHost = "ftp://localhost";
            String ftpUserName = "admin";
            String ftpPassword = "admin";
            Integer port = 21;
            String ftpPath = "/";
            String localPath = "F:\";
            String fileName = "111.jpg";
            //上传一个文件
            try {
    
    //            FileInputStream in = new FileInputStream(new File(localPath));
                FtpUtil2 ftpUtil = new FtpUtil2();
    
                ftpUtil.getFTPClient(ftpHost, ftpUserName, ftpPassword, port);
                // 上传文件
    //            boolean flag = ftpUtil.uploadFile(ftpPath, fileName, in);
                // 下载文件
                ftpUtil.downloadFtpFile("/1.jpg", localPath, fileName);
    //            if (flag) {
    //                System.out.println("文件上传ftp成功,请检查ftp服务器。");
    //
    //            } else {
    //                System.out.println("文件上传ftp异常。请重试!");
    //
    //            }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(e);
            }
        }
    
    }


    2.SFTP 工具类

    package com.example.demo.utlis;
    
    import com.jcraft.jsch.*;
    
    import java.io.*;
    import java.util.Properties;
    
    public class SFtpUtils {
    
        // 初始化单例对象
        private static SFtpUtils sFtpUtils = new SFtpUtils();
        private  String host;//服务器连接ip
        private String username;//用户名
        private String password;//密码
        private int port = 22;//端口号
        private ChannelSftp sftp = null;
        private Session sshSession = null;
    
        /**
         * 初始化sftp的单例对象
         * @return
         */
        public static SFtpUtils getInstance()
        {
            return sFtpUtils;
        }
    
    
        /**
         *  初始化sft链接信息,必须先做这个
         * @param host 远程主机ip
         * @param port 端口号
         * @param username 账号
         * @param password 密码
         */
        public  void init(String host, int port, String username, String password)
        {
            this.host = host;
            this.username = username;
            this.password = password;
            this.port = port;
    
        }
    
    
    
    
        /**
         * 通过SFTP连接服务器
         */
        public void connect()
        {
            try
            {
                JSch jsch = new JSch();
                jsch.getSession(username, host, port);
                sshSession = jsch.getSession(username, host, port);
                sshSession.setPassword(password);
                Properties sshConfig = new Properties();
                sshConfig.put("StrictHostKeyChecking", "no");
                sshSession.setConfig(sshConfig);
                sshSession.connect();
                Channel channel = sshSession.openChannel("sftp");
                channel.connect();
                sftp = (ChannelSftp) channel;
    
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    
        /**
         * 关闭连接
         */
        public void disconnect()
        {
            if (this.sftp != null)
            {
                if (this.sftp.isConnected())
                {
                    this.sftp.disconnect();
    
                }
            }
            if (this.sshSession != null)
            {
                if (this.sshSession.isConnected())
                {
                    this.sshSession.disconnect();
    
                }
            }
        }
    
        /**
         *  sftp下载文件
         * @param remoteFielPath  远程文件路径
         * @param localFilePath 本地下载路径
         * @return
         * @throws SftpException
         * @throws FileNotFoundException
         */
        public boolean downLoadFile(String remoteFielPath,String localFilePath) throws SftpException, FileNotFoundException {
            // 检查文件是否存在
            SftpATTRS sftpATTRS = sftp.lstat(remoteFielPath);
            if(!sftpATTRS.isReg()){
                // 不是一个文件,返回false
                return false;
            }
            // 下载文件到本地
            sftp.get(remoteFielPath,localFilePath);
    
            return true;
        }
    
        /**
         * 下载文件放回文件数据
         * @param remoteFielPath
         * @return
         * @throws SftpException
         * @throws IOException
         */
        public boolean downLoadFileTwo(String remoteFielPath, String localFilePath) throws SftpException, IOException {
            // 检查文件是否存在
            SftpATTRS sftpATTRS = sftp.lstat(remoteFielPath);
            // 判断是否是一个文件
            if(sftpATTRS.isReg()){
                // 下载文件到本地
                InputStream inputStream = sftp.get(remoteFielPath);
                /**今天想写下从sftp下载文件到本地,虽然sftp提供了get(String remotePath,String LocalPath)方法,将远程文件写入到本地。
                 * 但还是想属性下从远程获取InputStream对象写入到本地的方式。
                 * 遇到的问题:刚开始只想这实现,就是获取byte对象写入到本地文件,先用ByteArrayInputStream怎么转都无法获取到bytes对象
                 * 放入到FileOutputStream对象中。搞了老半天都没有搞定,或许有ByteArrayInputStream对象下载的方式但没有找到。
                 * 正解:如下*/
                // 通过BufferedInputStream对象缓存输入流对象获取远程的输入流
                BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                // 创建本地文件信息
                File file = new File(localFilePath);
                // 将本地文件放入到 本地文件输出流
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                // 将本地文件输出流 放入到 缓存输出流对象
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
                // 声明每次获取的byte长度
                int len = 2048;
                // 初始化byte[]
                byte[] bytes = new byte[len];
                /**通过BufferedInputStream对象获取 远程文件 InputStream的bytes字节信息,并循环添加到BufferedOutputStream缓存输出流对象中,
                 * 将远程bytes数据写入到本地文件中
                 * 遇到的问题:这里我一直纠结于为什么这样写会实现想要的效果,是如何写入到本地的
                 * 其实这不是开发中遇到的问题的事情了,是自己困于自己设定的一个纠结情绪中了。也就是俗称的牛角尖。
                 * 切记,一定不可以钻牛角尖。因为开发都是有语言规则的。按照规则来就能实现效果,脱离规则即使神仙也无能为力。
                 * */
                while ((len = bufferedInputStream.read(bytes)) != -1){
                    bufferedOutputStream.write(bytes,0,len);
                }
                bufferedOutputStream.flush();
                bufferedInputStream.close();
                bufferedOutputStream.close();
                fileOutputStream.close();
                inputStream.close();
                return true;
            }
            return false;
    
        }
        /**
         * 上传单个文件,通过文件路径上传
         * @param remotePath:远程保存目录
         * @param remoteFileName:保存文件名
         * @param localPath:本地上传目录(以路径符号结束)
         * @param localFileName:上传的文件名
         * @return
         */
        public boolean uploadFile(String remotePath, String remoteFileName,String localPath, String localFileName)
        {
            FileInputStream in = null;
            try
            {   // 创建目录
                createDir(remotePath);
                File file = new File(localPath + localFileName);
                in = new FileInputStream(file);
                sftp.put(in, remoteFileName);
                return true;
            }catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }catch (SftpException e)
            {
                e.printStackTrace();
            }
            finally
            {
                if (in != null)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            return false;
        }
    
        /**
         * 上传文件到sftp,通过输入流上传
         * @param remotePath
         * @param remoteFileName
         * @param inputStream
         * @return
         */
        public boolean uploadFile(String remotePath, String remoteFileName,InputStream inputStream)
        {
            FileInputStream in = null;
            try
            {   // 创建目录
                createDir(remotePath);
                sftp.put(inputStream, remoteFileName);
                return true;
            }catch (SftpException e)
            {
                e.printStackTrace();
            }
            finally
            {
                if (in != null)
                {
                    try
                    {
                        in.close();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            return false;
        }
    
        /**
         * 创建目录
         * @param createpath
         * @return
         */
        public boolean createDir(String createpath)
        {
            try
            {
                if (isDirExist(createpath))
                {
                    // 有时候,开发在填写路径的时候第一个位置会忘记加"/"的根路径
                    // 这回引发cd操作是发生:NO Such File 异常,所以这里处理下
                    if(!(createpath.substring(0,1)=="/")){
                        createpath="/"+createpath;
                    }
                    this.sftp.cd(createpath);
                    return true;
                }
                String pathArry[] = createpath.split("/");
                StringBuffer filePath = new StringBuffer("/");
                for (String path : pathArry)
                {
                    if (path.equals(""))
                    {
                        continue;
                    }
                    filePath.append(path + "/");
                    if (isDirExist(filePath.toString()))
                    {
                        sftp.cd(filePath.toString());
                    }
                    else
                    {
                        // 建立目录
                        sftp.mkdir(filePath.toString());
                        // 进入并设置为当前目录
                        sftp.cd(filePath.toString());
                    }
    
                }
                this.sftp.cd(createpath);
                return true;
            }
            catch (SftpException e)
            {
                e.printStackTrace();
            }
            return false;
        }
    
    
    
        /**
         * 判断目录是否存在,linux目录必须最前方带有"/"
         * @param directory
         * @return
         */
        public boolean isDirExist(String directory)
        {
            boolean isDirExistFlag = false;
            try
            {
                // 有时候,开发在填写路径的时候第一个位置会忘记加"/"的根路径
                // 这回引发cd操作是发生:NO Such File 异常,所以这里处理下
                if(!(directory.substring(0,1)=="/")){
                    directory="/"+directory;
                }
                SftpATTRS sftpATTRS = sftp.lstat(directory);
                isDirExistFlag = true;
                return sftpATTRS.isDir();
            }
            catch (Exception e)
            {
                if (e.getMessage().toLowerCase().equals("no such file"))
                {
                    isDirExistFlag = false;
                }
            }
            return isDirExistFlag;
        }
    
    
        public static void main(String arg[]) throws IOException, SftpException {
            // 获取图片的InputStream对象,并将图片生成到sftp上
            SFtpUtils sFtpUtils= SFtpUtils.getInstance();
            sFtpUtils.init("localhost",22, "admin", "admin");
            sFtpUtils.connect();
            // 上传文件
            /*File file = new File("F:\OK.jpg");
            InputStream in = new FileInputStream(file);
            boolean flag = sFtpUtils.uploadFile("/app/xwapp/Test","1111.jpg",in);*/
    
            // 下载文件到本地方法1
            // boolean flag = sFtpUtils.downLoadFile("/app/xwapp/Test/1111.jpg","F:\OKbak.jpg");
            // 下载文件到本地方法2
            boolean flag = sFtpUtils.downLoadFileTwo("/1.jpg","F:\OKbak.jpg");
            if(flag){
                System.out.println("处理成功");
            }else {
                System.out.println("处理失败");
            }
            sFtpUtils.disconnect();
        }
    }



    ////////////////////////////////////
    配置虚拟路径 application.properties
    # 虚拟路径配置(win系统自行变更本地路径)
    
    web.upload.path=F:/Test/
    
    spring.mvc.static-path-pattern=/**
    
    spring.resources.static-locations=file:${web.upload.path},classpath:/apk/,classpath:/static/
    
    

    本文来自博客园,作者:Forever丶随风,转载请注明原文链接:https://www.cnblogs.com/Forever-wind/p/14823073.html

  • 相关阅读:
    集合-ArrayList 源码解析
    >>《配色设计原理.pdf》
    >>《[美国视觉设计学院用书:完成设计(从理论到实践)].(萨马拉).温迪等.扫描版.pdf》
    《Photoshop智能手机APP界面设计.pdf》
    《贴心设计:打造高可用性的移动产品》——5.平板电脑和电子书阅读器
    3H Buy a Ticket —— Dij
    最短路板子
    3E A Simple Problem —— 数论
    3D 城池攻占 —— 左偏树
    3A Least Cost Bracket Sequence —— 贪心
  • 原文地址:https://www.cnblogs.com/Forever-wind/p/14823073.html
Copyright © 2011-2022 走看看