Java上传文件到服务器

avatar
作者
筋斗云
阅读量:1

1、使用jsch

        <!--sftp文件上传-->         <dependency>             <groupId>com.jcraft</groupId>             <artifactId>jsch</artifactId>             <version>0.1.55</version>         </dependency>

2、配置类

package com.base.jsch;  import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data @Component @ConfigurationProperties(prefix = "sftp") public class SFTPConfig {      /**      * SFTP 服务器地址IP地址      */     @NotBlank(message = "IP地址不能为空")     private  String ip;     /**      * SFTP 端口      */     @NotNull(message = "端口不能为空")     private  int port;     /**      * SFTP 登录用户名      */     @NotBlank(message = "用户名不能为空")     private  String username;     /**      * SFTP 登录密码      */     @NotBlank(message = "密码不能为空")     private  String password;     /**      * SFTP 私钥      */     private  String privateKey;     /**      * 上传失败隔多长时间重新上传      */      @NotNull(message = "上传失败重试间隔不能为空")     private  int uploadSleep;      /**      * 重新上传的次数      */     @NotNull(message = "重新上传次数不能为空")     private  int uploadRetry;      /**      * 服务器路径      */     @NotBlank(message = "服务器路径不能为空")     private  String serverStorageDir;      @NotNull(message = "文件名是否需要中文编码")     private  Boolean isFileNameGBK; } 

3、获取连接

package com.base.jsch;   import java.lang.reflect.Field; import java.util.Properties;   import com.jcraft.jsch.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;  /**  * SFTP工厂类,用于获取SFTP的连接和关闭SFTP的连接  */ @Slf4j @Component public class SFTPConnection {      @Autowired     private SFTPConfig sftpConfig;      private static ChannelSftp client;      private static Session session;       /**      * 建立连接      *      * @return client      */     public synchronized  ChannelSftp makeConnection() {         if (client == null || session == null || !client.isConnected() || !session.isConnected()) {             try {                 JSch jsch = new JSch();                 if (sftpConfig.getPrivateKey() != null) {                     jsch.addIdentity(sftpConfig.getPrivateKey());// 设置私钥                 }                 session = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getIp(),  sftpConfig.getPort());                 if (sftpConfig.getPassword() != null) {                     session.setPassword(sftpConfig.getPassword());                 }                 Properties config = new Properties();                 config.put("StrictHostKeyChecking", "no");                 session.setConfig(config);                 session.connect();                 client = (ChannelSftp)session.openChannel("sftp");                 client.connect();                 log.info("sftp服务器连接成功");                 // 文件名中文乱码                 if(Boolean.TRUE.equals(sftpConfig.getIsFileNameGBK())){                     try{                         Class<ChannelSftp> cl = ChannelSftp.class;                         Field f1 =cl.getDeclaredField("server_version");                         f1.setAccessible(true);                         f1.set(client, 2);                         client.setFilenameEncoding("gbk");                         log.info("设置中文编码");                     }catch (NoSuchFieldException | SftpException | IllegalAccessException e) {                         log.error("设置中文编码" + e.getMessage());                         throw new RuntimeException(e);                     }                 }              } catch (JSchException e) {                 log.error("主机sftp登录失败,检测登录ip,端口号,用户名密码是否正确,错误信息为" + e.getMessage());             }         }         return client;     }      /**      * 关闭连接      */     public void logout() {         if (client != null) {             if (client.isConnected()) {                 client.disconnect();             }         }         if (session != null) {             if (session.isConnected()) {                 session.disconnect();             }         }     }   } 

4、上传工具类

package com.base.jsch;  import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; import com.jcraft.jsch.SftpATTRS; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.SftpException;  /**  * 工具类  */ @Slf4j @Component public class SFTPClientUtils {      @Autowired     private SFTPConfig sftpConfig;      @Autowired     private SFTPConnection sftpConnection;       public synchronized boolean upload(InputStream fileIs, String fileName) {         boolean result = false;         int i = 0;         while (!result) {             log.info("*****开始登陆*****");             ChannelSftp sftp = sftpConnection.makeConnection();             if(null == sftp || !sftp.isConnected() || sftp.isClosed()){                 log.info("连接无效");                 return result;             }             log.info("******登陆成功*****");             try {                 sftp.cd(sftpConfig.getServerStorageDir());             } catch (SftpException e) {                 if(sftp.isConnected()){                     log.info("sftp文件上传,目录不存在开始创建");                     try {                         sftp.mkdir(sftpConfig.getServerStorageDir());                         sftp.cd(sftpConfig.getServerStorageDir());                     } catch (SftpException e1) {                         log.info("sftp文件上传,目录创建失败,错误信息:" + e1.fillInStackTrace());                     }                 }else{                     log.info("sftp连接已经失效");                     return result;                 }             }             try {                 sftp.put(fileIs, fileName, new FileProgressMonitor(fileIs.available()), ChannelSftp.OVERWRITE);                 // 用下面的方法不会调用进度监控                 //sftp.put(fileIs, fileName);                 if (i > 0) {                     log.info("sftp重试文件上传成功,ftp路径:" + sftpConfig.getServerStorageDir() + ",文件名称:" + fileName);                 } else {                     log.info("sftp文件上传成功,ftp路径为" + sftpConfig.getServerStorageDir() + ",文件名称:" + fileName);                 }                 result = true;             } catch (Exception e) {                 i++;                 log.error("sftp文件上传失败,重试中。。。第" + i + "次,错误信息" + e.fillInStackTrace());                 if (i > sftpConfig.getUploadRetry()) {                     sftpConnection.logout();                     log.error("sftp文件上传失败,超过重试次数结束重试,错误信息" + e.fillInStackTrace());                     return result;                 }                 try {                     TimeUnit.MILLISECONDS.sleep(sftpConfig.getUploadSleep());                 } catch (InterruptedException e1) {                     sftpConnection.logout();                     e1.printStackTrace();                     log.error("sftp文件上传失败,系统检测出异常:" + e);                 }             }          }         sftpConnection.logout();         log.info("sftp上传:" + result);         try {             fileIs.close();         } catch (IOException e) {             throw new RuntimeException(e);         }         return result;     }      public synchronized void download(String directory, String downloadFile, String localDir) {         log.info("*****开始登陆*****");         ChannelSftp sftp = sftpConnection.makeConnection();         log.info("******登陆成功*****");         if (directory != null && !"".equals(directory)) {             try {                 sftp.cd(directory);             } catch (SftpException e) {                 log.error("sftp文件下载,目录不存在,错误信息" + e.fillInStackTrace());             }         }         String src = directory + "/" + downloadFile;         try {             SftpATTRS attr = sftp.stat(src);             long fileSize = attr.getSize();             InputStream inputStream = sftp.get(src, new FileProgressMonitor(fileSize));             // 用下面的方法不会调用进度监控             //InputStream inputStream = sftp.get(src);             String tempFile = localDir + "/" + downloadFile;             File file = new File(tempFile);             File fileParent = file.getParentFile();             if (!fileParent.exists()) {                 fileParent.mkdirs();             }             if (!file.exists()) {                 writeToLocal(tempFile, inputStream);             }         } catch (SftpException e) {             e.printStackTrace();         } catch (IOException e) {             e.printStackTrace();         }         sftpConnection.logout();     }   //    /** //     * 文件上传 将文件对象上传到sftp作为文件。文件完整路径=basePath+directory 目录不存在则会上传文件夹 //     * //     * @param basePath  服务器的基础路径,服务器上必须有该目录,例如 /home //     * @param directory 上传到的目录,服务器上没有会自动创建,有则不创建,例如 /test //     * @param fileIs    文件流 //     * @param fileName  放到服务器上要保存的名字,例如 码海无际.txt //     * @return //     */ //    public synchronized static boolean upload(String basePath, String directory, InputStream fileIs, String fileName) { //        boolean result = false; //        Integer i = 0; //        while (!result) { //            log.info("*****开始登陆*****"); //            ChannelSftp sftp = SFTPConnectionFactory.makeConnection(); //            log.info("******登陆成功*****"); //            try { //                sftp.cd(basePath); //                sftp.cd(directory); //            } catch (SftpException e) { //                log.info("sftp文件上传,目录不存在开始创建"); //                String[] dirs = directory.split("/"); //                String tempPath = basePath; //                for (String dir : dirs) { //                    if (null == dir || "".equals(dir)) { //                        continue; //                    } //                    tempPath += "/" + dir; //                    try { //                        sftp.cd(tempPath); //                    } catch (SftpException ex) { //                        try { //                            sftp.mkdir(tempPath); //                            sftp.cd(tempPath); //                        } catch (SftpException e1) { //                            log.info("sftp文件上传,目录创建失败,错误信息:" + e1.fillInStackTrace()); //                        } //                    } //                } //            } //            try { //                sftp.put(fileIs, fileName, new FileProgressMonitor(fileIs.available()), ChannelSftp.OVERWRITE); //                // 用下面的方法不会调用进度监控 //                //sftp.put(fileIs, fileName); //                if (i > 0) { //                    log.info("sftp重试文件上传成功,ftp路径:" + basePath + directory + ",文件名称:" + fileName); //                } else { //                    log.info("sftp文件上传成功,ftp路径为" + basePath + directory + ",文件名称:" + fileName); //                } //                result = true; //            } catch (Exception e) { //                i++; //                log.error("sftp文件上传失败,重试中。。。第" + i + "次,错误信息" + e.fillInStackTrace()); //                if (i > uploadRettry) { //                    SFTPConnectionFactory.logout(); //                    log.error("sftp文件上传失败,超过重试次数结束重试,错误信息" + e.fillInStackTrace()); //                    return result; //                } //                try { //                    TimeUnit.MILLISECONDS.sleep(uploadSleep); //                } catch (InterruptedException e1) { //                    SFTPConnectionFactory.logout(); //                    e1.printStackTrace(); //                    log.error("sftp文件上传失败,系统检测出异常:" + e); //                } //            } // //        } //        SFTPConnectionFactory.logout(); //        log.info("sftp上传:" + result); //        try { //            fileIs.close(); //        } catch (IOException e) { //            throw new RuntimeException(e); //        } //        return result; //    }   //    /** //     * 下载文件至本地 //     * //     * @param directory    要下载文件所在目录,例如 /home //     * @param downloadFile 要下载的文件,例如 码海无际.txt //     * @param localDir     本地路径,例如 D:\\home //     * @return //     */ //    public synchronized static void download(String directory, String downloadFile, String localDir) { //        log.info("*****开始登陆*****"); //        ChannelSftp sftp = SFTPConnectionFactory.makeConnection(); //        log.info("******登陆成功*****"); //        if (directory != null && !"".equals(directory)) { //            try { //                sftp.cd(directory); //            } catch (SftpException e) { //                log.error("sftp文件下载,目录不存在,错误信息" + e.fillInStackTrace()); //            } //        } //        String src = directory + "/" + downloadFile; //        try { //            SftpATTRS attr = sftp.stat(src); //            long fileSize = attr.getSize(); //            InputStream inputStream = sftp.get(src, new FileProgressMonitor(fileSize)); //            // 用下面的方法不会调用进度监控 //            //InputStream inputStream = sftp.get(src); //            String tempFile = localDir + "/" + downloadFile; //            File file = new File(tempFile); //            File fileParent = file.getParentFile(); //            if (!fileParent.exists()) { //                fileParent.mkdirs(); //            } //            if (!file.exists()) { //                writeToLocal(tempFile, inputStream); //            } //        } catch (SftpException e) { //            e.printStackTrace(); //        } catch (IOException e) { //            e.printStackTrace(); //        } //        SFTPConnectionFactory.logout(); //    }      /**      * 将InputStream写入本地文件      *      * @param destination 写入本地目录      * @param input       输入流      * @throws IOException 异常      */     public static void writeToLocal(String destination, InputStream input) throws IOException {         int index;         byte[] bytes = new byte[1024];         FileOutputStream downloadFile = new FileOutputStream(destination);         while ((index = input.read(bytes)) != -1) {             downloadFile.write(bytes, 0, index);             downloadFile.flush();         }         downloadFile.close();         input.close();     }      /**      * 删除文件      *      * @param directory  要删除文件所在目录,例如 /home      * @param deleteFile 要删除的文件,例如 码海无际.txt      */     public synchronized  boolean delete(String directory, String deleteFile) {         boolean result = false;         ChannelSftp sftp = sftpConnection.makeConnection();         try {             sftp.cd(directory);             sftp.rm(deleteFile);         } catch (SftpException e) {             e.printStackTrace();         }         result = true;         sftpConnection.logout();         return result;     }    } 

5、上传进度

package com.base.jsch;  import com.jcraft.jsch.SftpProgressMonitor; import lombok.extern.slf4j.Slf4j;  import java.text.DecimalFormat; @Slf4j public class FileProgressMonitor implements SftpProgressMonitor {     private long fileSize; // 记录文件总大小      private long transfered; // 记录已传输的数据总大小      public FileProgressMonitor(long fileSize) {         if (fileSize != 0) {             this.fileSize = fileSize;             log.info("数据大小: " + fileSize + " bytes");         } else {             log.info("文件错误");         }     }      @Override     public void init(int op, String src, String dest, long max) {         log.info("开始");     }      /**      * 实现了SftpProgressMonitor接口的count方法      */     @Override     public boolean count(long count) {         add(count);         return true;     }      /**      * 实现了SftpProgressMonitor接口的end方法      */     @Override     public void end() {         log.info("结束");     }      private synchronized void add(long count) {         transfered = transfered + count;         log.info("已传输数据大小: " + transfered + " bytes");         double d = ((double) transfered * 100) / (double) fileSize;         DecimalFormat df = new DecimalFormat("#.##");         log.info("已传输数据占比: " + df.format(d) + "%");     }  } 

6、配置文件

sftp:   ip: 192.168.1.111   port: 22   username: root   password: root   uploadSleep: 1000 #上传失败隔1秒重新上传   uploadRettry: 1 #重新上传的次数   serverStorageDir: /opt/zzz #服务器路径   isFileNameGBK: true #文件名是否gbk编码

7、上传测试

String src = "D:\\home\\test.xlsx"; // 本地文件名 File file = new File(src); try (FileInputStream fis = new FileInputStream(file)) {     boolean upload = sftpClientUtils.upload(fis, ele.getName()); } catch (IOException e) {     e.printStackTrace(); }

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!