zoukankan      html  css  js  c++  java
  • ftp连接池客户端

    1、添加ftp配置

     1 package com.scenetec.isv.utils.ftp.config;
     2 
     3 import lombok.Getter;
     4 import lombok.Setter;
     5 import org.apache.commons.net.ftp.FTP;
     6 import org.springframework.boot.context.properties.ConfigurationProperties;
     7 import org.springframework.stereotype.Component;
     8 
     9 /**
    10  * @author shendunyuan@scenetec.com
    11  * @date 2018/12/19
    12  */
    13 @Getter
    14 @Setter
    15 @Component
    16 @ConfigurationProperties(ignoreUnknownFields = false, prefix = "ftp.client")
    17 public class FtpClientProperties {
    18 
    19     /**
    20      * ftp地址
    21      */
    22     private String host;
    23 
    24     /**
    25      * 端口号
    26      */
    27     private Integer port = 21;
    28 
    29     /**
    30      * 登录用户
    31      */
    32     private String username;
    33 
    34     /**
    35      * 登录密码
    36      */
    37     private String password;
    38 
    39     /**
    40      * 被动模式
    41      */
    42     private boolean passiveMode = false;
    43 
    44     /**
    45      * 编码
    46      */
    47     private String encoding = "UTF-8";
    48 
    49     /**
    50      * 连接超时时间(秒)
    51      */
    52     private Integer connectTimeout;
    53 
    54     /**
    55      * 缓冲大小
    56      */
    57     private Integer bufferSize = 1024;
    58 
    59     /**
    60      * 设置keepAlive
    61      * 单位:秒  0禁用
    62      */
    63     private Integer keepAliveTimeout = 0;
    64 
    65     /**
    66      * 传输文件类型
    67      */
    68     private Integer transferFileType = FTP.BINARY_FILE_TYPE;
    69 
    70 }
    View Code
    1 ftp:
    2  client:
    3     host: 132.232.68.30
    4     port: 21
    5     username: isv
    6     password: xintai1234
    7     passiveMode: true
    View Code

    2、ftp客户端工厂处理类

      1 package com.scenetec.isv.utils.ftp.core;
      2 
      3 import com.scenetec.isv.utils.ftp.config.FtpClientProperties;
      4 import lombok.extern.slf4j.Slf4j;
      5 import org.apache.commons.net.ftp.FTPClient;
      6 import org.apache.commons.net.ftp.FTPReply;
      7 import org.apache.commons.pool2.BasePooledObjectFactory;
      8 import org.apache.commons.pool2.PooledObject;
      9 import org.apache.commons.pool2.impl.DefaultPooledObject;
     10 import org.springframework.stereotype.Component;
     11 
     12 /**
     13  * @author shendunyuan@scenetec.com
     14  * @date 2018/12/19
     15  */
     16 @Slf4j
     17 @Component
     18 public class FtpClientFactory extends BasePooledObjectFactory<FTPClient> {
     19 
     20     private FtpClientProperties config;
     21 
     22     public FtpClientFactory(FtpClientProperties config) {
     23         this.config = config;
     24     }
     25 
     26     @Override
     27     public FTPClient create() {
     28 
     29         FTPClient ftpClient = new FTPClient();
     30         ftpClient.setControlEncoding(config.getEncoding());
     31         if (null != config.getConnectTimeout()) {
     32             ftpClient.setConnectTimeout(config.getConnectTimeout());
     33         }
     34 
     35         try {
     36             ftpClient.connect(config.getHost(), config.getPort());
     37             int replyCode = ftpClient.getReplyCode();
     38             if (!FTPReply.isPositiveCompletion(replyCode)) {
     39                 ftpClient.disconnect();
     40                 log.warn("FTPServer refused connection,replyCode:{}", replyCode);
     41                 return null;
     42             }
     43 
     44             if (!ftpClient.login(config.getUsername(), config.getPassword())) {
     45                 log.warn("FTPClient login failed... username is {}; password: {}", config.getUsername(), config.getPassword());
     46             }
     47 
     48             ftpClient.setBufferSize(config.getBufferSize());
     49             ftpClient.setFileType(config.getTransferFileType());
     50             if (config.isPassiveMode()) {
     51                 ftpClient.enterLocalPassiveMode();
     52             }
     53 
     54         } catch (Exception ex) {
     55             ex.printStackTrace();
     56             log.error("Failed to create FTP connection");
     57         }
     58 
     59         return ftpClient;
     60     }
     61 
     62     void destroyObject(FTPClient client) {
     63         destroyObject(wrap(client));
     64     }
     65 
     66     /**
     67      * 用PooledObject封装对象放入池中
     68      * @param ftpClient ftp客户端
     69      * @return 默认池对象
     70      */
     71     @Override
     72     public PooledObject<FTPClient> wrap(FTPClient ftpClient) {
     73         return new DefaultPooledObject<>(ftpClient);
     74     }
     75 
     76     /**
     77      * 销毁FtpClient对象
     78      * @param ftpPooled ftp池对象
     79      */
     80     @Override
     81     public void destroyObject(PooledObject<FTPClient> ftpPooled) {
     82         if (ftpPooled == null) {
     83             return;
     84         }
     85 
     86         FTPClient ftpClient = ftpPooled.getObject();
     87 
     88         close(ftpClient);
     89     }
     90 
     91     /**
     92      * 销毁FtpClient对象
     93      * @param client ftp对象
     94      */
     95     public void close(FTPClient client) {
     96         try {
     97             if (client.isConnected()) {
     98                 client.logout();
     99             }
    100         } catch (Exception ex) {
    101             ex.printStackTrace();
    102             log.error("Failure to destroy FTP connection pool.");
    103         } finally {
    104             try {
    105                 client.disconnect();
    106             } catch (Exception ex) {
    107                 ex.printStackTrace();
    108                 log.error("Failed to close FTP connection pool.");
    109             }
    110         }
    111     }
    112 
    113     /**
    114      * 验证FtpClient对象
    115      * @param ftpPooled ftp池对象
    116      * @return 发送一个NOOP命令到FTP服务器,如果成功返回true,否则为false。
    117      */
    118     @Override
    119     public boolean validateObject(PooledObject<FTPClient> ftpPooled) {
    120         try {
    121             FTPClient ftpClient = ftpPooled.getObject();
    122             if (ftpClient == null) {
    123                 return false;
    124             }
    125             if (!ftpClient.isConnected()) {
    126                 return false;
    127             }
    128             return ftpClient.sendNoOp();
    129         } catch (Exception ex) {
    130             ex.printStackTrace();
    131         }
    132         return false;
    133     }
    134 
    135 }
    View Code

    3、ftp资源池处理类

      1 package com.scenetec.isv.utils.ftp.core;
      2 
      3 import lombok.extern.slf4j.Slf4j;
      4 import org.apache.commons.net.ftp.FTPClient;
      5 import org.apache.commons.pool2.BaseObjectPool;
      6 import org.springframework.util.ObjectUtils;
      7 
      8 import java.util.NoSuchElementException;
      9 import java.util.concurrent.ArrayBlockingQueue;
     10 import java.util.concurrent.BlockingQueue;
     11 import java.util.concurrent.TimeUnit;
     12 
     13 /**
     14  * @author shendunyuan@scenetec.com
     15  * @date 2018/12/19
     16  */
     17 @Slf4j
     18 public class FtpClientPool extends BaseObjectPool<FTPClient> {
     19 
     20     private static final int DEFAULT_POOL_SIZE = 5;
     21     private final BlockingQueue<FTPClient> pool;
     22     private final FtpClientFactory factory;
     23 
     24 
     25     /**
     26      * 初始化连接池,需要注入一个工厂来提供FTPClient实例
     27      * @param factory
     28      */
     29     public FtpClientPool(FtpClientFactory factory) {
     30         this(DEFAULT_POOL_SIZE, factory);
     31     }
     32 
     33     public FtpClientPool(int poolSize, FtpClientFactory factory) {
     34         this.factory = factory;
     35         this.pool = new ArrayBlockingQueue<>(poolSize * 2);
     36         initPool(poolSize);
     37     }
     38 
     39     /**
     40      * 初始化连接池,需要注入一个工厂来提供FTPClient实例
     41      * @param maxPoolSize
     42      */
     43     private void initPool(int maxPoolSize) {
     44         try {
     45             for (int i = 0; i < maxPoolSize; i++) {
     46                 addObject();
     47             }
     48         } catch (Exception ex) {
     49             ex.printStackTrace();
     50             throw new RuntimeException("Failed to initialize FTP thread pool.");
     51         }
     52     }
     53 
     54     /**
     55      * 客户端从池中借出一个对象
     56      * @return
     57      * @throws Exception
     58      * @throws NoSuchElementException
     59      * @throws IllegalStateException
     60      */
     61     @Override
     62     public FTPClient borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
     63         FTPClient client = pool.take();
     64         if (ObjectUtils.isEmpty(client)) {
     65             // 创建新的连接
     66             client = factory.create();
     67         }
     68         // 验证对象是否有效
     69         else if (!factory.validateObject(factory.wrap(client))) {
     70             // 对无效的对象进行处理
     71             invalidateObject(client);
     72             // 创建新的对象
     73             client = factory.create();
     74         }
     75         // 返回ftp对象
     76         return client;
     77     }
     78 
     79     /**
     80      * 返还对象到连接池中
     81      * @param client
     82      * @throws Exception
     83      */
     84     @Override
     85     public void returnObject(FTPClient client) {
     86         try {
     87             long timeout = 3L;
     88             if (client != null) {
     89                 if (client.isConnected()) {
     90                     if (pool.size() < DEFAULT_POOL_SIZE) {
     91                         // 添加回队列
     92                         if (!pool.offer(client, timeout, TimeUnit.SECONDS)) {
     93                             factory.destroyObject(client);
     94                         }
     95                     } else {
     96                         factory.destroyObject(client);
     97                     }
     98                 } else {
     99                     factory.destroyObject(client);
    100                 }
    101             }
    102         } catch (Exception ex) {
    103             ex.printStackTrace();
    104             log.error("Failed to return FTP connection object.");
    105         }
    106     }
    107 
    108     /**
    109      * 移除无效的对象
    110      * @param client
    111      * @throws Exception
    112      */
    113     @Override
    114     public void invalidateObject(FTPClient client) {
    115         try {
    116             // 移除无效对象
    117             pool.remove(client);
    118             // 注销对象
    119             factory.destroyObject(client);
    120         } catch (Exception ex) {
    121             ex.printStackTrace();
    122             log.error("Failed to remove invalid FTP object.");
    123         }
    124     }
    125 
    126     /**
    127      * 增加一个新的链接,超时失效
    128      * @throws Exception
    129      * @throws IllegalStateException
    130      * @throws UnsupportedOperationException
    131      */
    132     @Override
    133     public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
    134         pool.offer(factory.create(), 3, TimeUnit.SECONDS);
    135     }
    136 
    137     @Override
    138     public void close() {
    139         try {
    140             while (pool.iterator().hasNext()) {
    141                 FTPClient client = pool.take();
    142                 factory.destroyObject(client);
    143             }
    144         } catch (Exception ex) {
    145             ex.printStackTrace();
    146             log.error("Failed to close FTP object.");
    147         }
    148     }
    149 }
    View Code

    4、ftp上传下载基础处理类

      1 package com.scenetec.isv.utils.ftp.template;
      2 
      3 import lombok.extern.slf4j.Slf4j;
      4 import org.apache.commons.lang3.StringUtils;
      5 import org.apache.commons.net.ftp.FTPClient;
      6 
      7 import java.io.*;
      8 
      9 /**
     10  * @author shendunyuan@scenetec.com
     11  * @date 2019/1/22
     12  */
     13 @Slf4j
     14 public abstract class FtpBaseTemplate {
     15 
     16     /**
     17      * 上传文件
     18      *
     19      * @param localPath 本地路径
     20      * @param remotePath 远程路径,必须包含文件名("/"为当前ftp用户根路径)
     21      * @return 上传成功返回true, 否则返回false
     22      */
     23     public boolean uploadFile(String localPath, String remotePath) {
     24         if (StringUtils.isBlank(localPath)) {
     25             log.error("本地文件路径为空");
     26             return false;
     27         }
     28         return uploadFile(new File(localPath), remotePath);
     29     }
     30 
     31     /**
     32      * 上传文件
     33      *
     34      * @param localFile 本地文件
     35      * @param remotePath 远程文件,必须包含文件名
     36      * @return 上传成功返回true, 否则返回false
     37      */
     38     public boolean uploadFile(File localFile, String remotePath) {
     39         if (!localFile.exists()) {
     40             log.error("本地文件不存在");
     41             return false;
     42         }
     43         if (!localFile.isFile()) {
     44             log.error("上传类型不是文件");
     45         }
     46         if (StringUtils.isBlank(remotePath)) {
     47             remotePath = "/";
     48         }
     49         FileInputStream fis = null;
     50         BufferedInputStream bis = null;
     51         try {
     52             fis = new FileInputStream(localFile);
     53             bis = new BufferedInputStream(fis);
     54             // 上传
     55             return uploadFile(bis, remotePath);
     56         } catch (FileNotFoundException fex) {
     57             fex.printStackTrace();
     58             log.error("系统找不到指定的文件:{}", localFile);
     59         } catch (Exception ex) {
     60             ex.printStackTrace();
     61             log.error("上传文件异常。");
     62         } finally {
     63             try {
     64                 if (bis != null) {
     65                     bis.close();
     66                 }
     67             } catch (Exception ex) {
     68                 ex.printStackTrace();
     69             }
     70             try {
     71                 if (fis != null) {
     72                     fis.close();
     73                 }
     74             } catch (Exception ex) {
     75                 ex.printStackTrace();
     76             }
     77         }
     78         return false;
     79     }
     80 
     81     /**
     82      * 上传文件
     83      *
     84      * @param fileContent 文件内容
     85      * @param remotePath 远程文件,必须包含文件名
     86      * @return 上传成功返回true, 否则返回false
     87      */
     88     public boolean uploadFile(byte[] fileContent, String remotePath) {
     89         if (fileContent == null || fileContent.length <= 0) {
     90             log.error("上传文件内容为空。");
     91             return false;
     92         }
     93         InputStream is = null;
     94         try {
     95             is = new ByteArrayInputStream(fileContent);
     96             // 上传
     97             return uploadFile(is, remotePath);
     98         } catch (Exception ex) {
     99             ex.printStackTrace();
    100             log.error("上传文件异常。原因:【{}】", ex.getMessage());
    101         } finally {
    102             try {
    103                 if (is != null) {
    104                     is.close();
    105                 }
    106             } catch (Exception ex) {
    107                 ex.printStackTrace();
    108             }
    109         }
    110         return false;
    111     }
    112 
    113     /**
    114      * 下载文件
    115      * @param remotePath 远程文件,必须包含文件名
    116      * @param localPath 本地路径,必须包含文件名(全路径)
    117      * @return 下载成功返回true,否则返回false
    118      */
    119     public boolean downloadFile(String remotePath, String localPath) {
    120         if (StringUtils.isBlank(remotePath)) {
    121             remotePath = "/";
    122         }
    123         if (StringUtils.isBlank(localPath)) {
    124             log.error("本地文件路径为空");
    125             return false;
    126         }
    127         return downloadFile(new File(localPath), remotePath);
    128     }
    129 
    130     /**
    131      * 下载文件
    132      * @param remotePath 远程文件,必须包含文件名
    133      * @param localFile 本地文件
    134      * @return 下载成功返回true,否则返回false
    135      */
    136     public boolean downloadFile(File localFile, String remotePath) {
    137         // 创建本地文件路径
    138         if (!localFile.exists()) {
    139             File parentFile = localFile.getParentFile();
    140             if (!parentFile.exists()) {
    141                 boolean bool = parentFile.mkdirs();
    142                 if (!bool) {
    143                     log.error("创建本地路径失败");
    144                     return false;
    145                 }
    146             }
    147         }
    148         OutputStream os = null;
    149         try {
    150             os = new FileOutputStream(localFile);
    151             // 下载
    152             return downloadFile(remotePath, os);
    153         } catch (Exception ex) {
    154             ex.printStackTrace();
    155             log.error("下载文件异常。原因:【{}】", ex.getMessage());
    156         } finally {
    157             try {
    158                 if (os != null) {
    159                     os.close();
    160                 }
    161             } catch (Exception ex) {
    162                 ex.printStackTrace();
    163             }
    164         }
    165         return false;
    166     }
    167 
    168     /**
    169      * 删除文件
    170      * @param remotePath 远程文件,必须包含文件名
    171      * @return 删除成功返回true,否则返回false
    172      */
    173     public boolean deleteFile(String remotePath) {
    174         if (StringUtils.isBlank(remotePath)) {
    175             log.info("远程路径为空");
    176             return false;
    177         }
    178         return deleFile(remotePath);
    179     }
    180 
    181     /**
    182      * 上传文件
    183      * @param inputStream 文件流
    184      * @param remotePath 远程路径,必须包含文件名
    185      * @return 上传成功返回true,否则返回false
    186      */
    187     protected abstract boolean uploadFile(InputStream inputStream, String remotePath);
    188     /**
    189      * 下载文件
    190      * @param remotePath 远程文件,必须包含文件名
    191      * @param outputStream 本地文件流
    192      * @return 下载成功返回true,否则返回false
    193      */
    194     protected abstract boolean downloadFile(String remotePath, OutputStream outputStream);
    195     /**
    196      * 删除文件
    197      * @param remotePath 程文件,必须包含文件名
    198      * @return 删除成功返回true,否则返回false
    199      */
    200     protected abstract boolean deleFile(String remotePath);
    201 
    202     /**
    203      * 上传文件
    204      *
    205      * @param client ftp客户端
    206      * @param inputStream 文件流
    207      * @param remotePath 远程文件,必须包含文件名
    208      * @return 上传成功返回true, 否则返回false
    209      */
    210     protected boolean uploadHandle(FTPClient client, InputStream inputStream, String remotePath) {
    211         // 上传
    212         try {
    213             // 获取远程文件路径
    214             String remoteFilePath = getRemoteFilePath(remotePath);
    215             // 获取远程文件名
    216             String remoteFileName = getRemoteFileName(remotePath);
    217             // 切换工作路径
    218             boolean bool = changeDirectory(client, remoteFilePath);
    219             if (!bool) {
    220                 log.error("切换工作路径失败,{}", client.getReplyString());
    221                 return false;
    222             }
    223             // 设置重试次数
    224             final int retryTime = 3;
    225             boolean retryResult = false;
    226 
    227             for (int i = 0; i <= retryTime; i++) {
    228                 boolean success = client.storeFile(remoteFileName, inputStream);
    229                 if (success) {
    230                     log.info("文件【{}】上传成功。", remotePath);
    231                     retryResult = true;
    232                     break;
    233                 } else {
    234                     log.error("文件上传失败。{}", client.getReplyString());
    235                 }
    236                 log.warn("文件【{}】上传失败,重试上传...尝试{}次", remotePath, i);
    237             }
    238 
    239             return retryResult;
    240         } catch (Exception ex) {
    241             ex.printStackTrace();
    242             log.error("上传文件异常。");
    243         }
    244 
    245         return false;
    246     }
    247 
    248     /**
    249      * 下载文件
    250      * @param client ftp客户端
    251      * @param remotePath 远程文件,必须包含文件名
    252      * @param outputStream 本地文件流
    253      * @return 下载成功返回true,否则返回false
    254      */
    255     protected boolean downloadHandle(FTPClient client, String remotePath, OutputStream outputStream) {
    256         // 下载
    257         try {
    258             // 获取远程文件路径
    259             String remoteFilePath = getRemoteFilePath(remotePath);
    260             // 获取远程文件名
    261             String remoteFileName = getRemoteFileName(remotePath);
    262             // 切换工作路径
    263             boolean bool = client.changeWorkingDirectory(remoteFilePath);
    264             if (!bool) {
    265                 log.error("切换工作路径失败,{}", client.getReplyString());
    266                 return false;
    267             }
    268             // 设置重试次数
    269             final int retryTime = 3;
    270             boolean retryResult = false;
    271 
    272             for (int i = 0; i <= retryTime; i++) {
    273                 boolean success = client.retrieveFile(remoteFileName, outputStream);
    274                 if (success) {
    275                     log.info("文件【{}】下载成功。", remotePath);
    276                     retryResult = true;
    277                     break;
    278                 } else {
    279                     log.error("文件下载失败。 {}", client.getReplyString());
    280                 }
    281                 log.warn("文件【{}】下载失败,重试下载...尝试{}次", remotePath, i);
    282             }
    283             // 返回结果
    284             return retryResult;
    285         } catch (Exception ex) {
    286             ex.printStackTrace();
    287             log.error("下载文件异常。");
    288         } finally {
    289 
    290         }
    291         return false;
    292     }
    293 
    294     /**
    295      * 删除文件
    296      * @param remotePath 远程文件,必须包含文件名
    297      * @return 删除成功返回true,否则返回false
    298      */
    299     protected boolean deleteHandle(FTPClient client, String remotePath) {
    300         try {
    301             // 删除文件
    302             boolean bool = client.deleteFile(remotePath);
    303             if (!bool) {
    304                 log.error("删除文件失败,{}", client.getReplyString());
    305             }
    306             return bool;
    307         } catch (Exception ex) {
    308             ex.printStackTrace();
    309             log.error("删除文件异常。");
    310         }
    311         return false;
    312     }
    313 
    314     /**
    315      * 获取远程工作目录
    316      * @param remotePath 远程路径
    317      * @return 返回工作路径
    318      */
    319     private String getRemoteFilePath(String remotePath) {
    320         if (StringUtils.isNotBlank(remotePath)) {
    321             return remotePath.substring(0, remotePath.lastIndexOf("/") + 1);
    322         }
    323         return "/";
    324     }
    325 
    326     /**
    327      * 获取远程文件名
    328      * @param remotePath 远程路径
    329      * @return 返回文件名
    330      */
    331     private String getRemoteFileName(String remotePath) {
    332         if (StringUtils.isNotBlank(remotePath)) {
    333             return remotePath.substring(remotePath.lastIndexOf("/") + 1);
    334         }
    335         return "";
    336     }
    337 
    338     /**
    339      * 切换工作目录
    340      * @param client ftp客户端
    341      * @param dir 工作目录
    342      * @return 切换成功返回true,否则返回false
    343      */
    344     private boolean changeDirectory(FTPClient client, String dir) {
    345         try {
    346             if (client == null || StringUtils.isBlank(dir)) {
    347                 return false;
    348             }
    349 
    350             String fileBackslashSeparator = "\";
    351             String fileSeparator = "/";
    352 
    353             if (StringUtils.contains(dir, fileBackslashSeparator)) {
    354                 dir = StringUtils.replaceAll(dir, fileBackslashSeparator, fileSeparator);
    355             }
    356 
    357             String[] dirArray = StringUtils.split(dir, fileSeparator);
    358 
    359             String tmp = "";
    360             for (String aDirArray : dirArray) {
    361                 tmp += fileSeparator + aDirArray;
    362                 if (!client.changeWorkingDirectory(tmp)) {
    363                     // 创建工作目录
    364                     client.makeDirectory(tmp);
    365                     // 切换工作目录
    366                     client.changeWorkingDirectory(tmp);
    367                 }
    368             }
    369             return true;
    370         } catch (Exception ex) {
    371             ex.printStackTrace();
    372             log.error("切换工作目录失败。");
    373         }
    374         return false;
    375     }
    376 
    377 }
    View Code

    5、ftp一次连接处理上传下载

     1 package com.scenetec.isv.utils.ftp.template;
     2 
     3 import com.scenetec.isv.utils.ftp.core.FtpClientFactory;
     4 import lombok.extern.slf4j.Slf4j;
     5 import org.apache.commons.net.ftp.FTPClient;
     6 import org.springframework.stereotype.Component;
     7 
     8 import javax.annotation.Resource;
     9 import java.io.InputStream;
    10 import java.io.OutputStream;
    11 
    12 /**
    13  * @author shendunyuan@scenetec.com
    14  * @date 2019/1/22
    15  */
    16 @Slf4j
    17 @Component
    18 public class FtpOnceTemplate extends FtpBaseTemplate {
    19 
    20     @Resource
    21     private FtpClientFactory factory;
    22 
    23     /**
    24      * 上传文件
    25      *
    26      * @param inputStream 文件流
    27      * @param remotePath 远程文件,必须包含文件名
    28      * @return 上传成功返回true, 否则返回false
    29      */
    30     @Override
    31     public boolean uploadFile(InputStream inputStream, String remotePath) {
    32         // 上传
    33         FTPClient client = null;
    34         try {
    35             // 创建对象
    36             client = factory.create();
    37             // 上传
    38             return uploadHandle(client, inputStream, remotePath);
    39         } catch (Exception ex) {
    40             ex.printStackTrace();
    41             log.error("上传文件异常。");
    42         } finally {
    43             factory.close(client);
    44         }
    45         return false;
    46     }
    47 
    48     /**
    49      * 下载文件
    50      * @param remotePath 远程文件,必须包含文件名
    51      * @param outputStream 本地文件流
    52      * @return 下载成功返回true,否则返回false
    53      */
    54     @Override
    55     public boolean downloadFile(String remotePath, OutputStream outputStream) {
    56         // 下载
    57         FTPClient client = null;
    58         try {
    59             // 获取对象
    60             client = factory.create();
    61             // 文件下载
    62             return downloadHandle(client, remotePath, outputStream);
    63         } catch (Exception ex) {
    64             ex.printStackTrace();
    65             log.error("下载文件异常。");
    66         } finally {
    67             if (client != null) {
    68                 factory.close(client);
    69             }
    70         }
    71         return false;
    72     }
    73 
    74     /**
    75      * 删除文件
    76      * @param remotePath 远程文件,必须包含文件名
    77      * @return 下载成功返回true,否则返回false
    78      */
    79     @Override
    80     public boolean deleFile(String remotePath) {
    81         FTPClient client = null;
    82         try {
    83             // 获取对象
    84             client = factory.create();
    85             // 删除文件
    86             return deleteHandle(client, remotePath);
    87         } catch (Exception ex) {
    88             ex.printStackTrace();
    89             log.error("删除文件异常。");
    90         } finally {
    91             if (client != null) {
    92                 factory.close(client);
    93             }
    94         }
    95         return false;
    96     }
    97 
    98 }
    View Code

    6、ftp使用资源池处理上传下载

      1 package com.scenetec.isv.utils.ftp.template;
      2 
      3 import com.scenetec.isv.utils.ftp.core.FtpClientFactory;
      4 import lombok.extern.slf4j.Slf4j;
      5 import org.apache.commons.net.ftp.FTPClient;
      6 import org.apache.commons.net.ftp.FTPReply;
      7 import org.apache.commons.pool2.impl.GenericObjectPool;
      8 import org.springframework.stereotype.Component;
      9 
     10 import java.io.InputStream;
     11 import java.io.OutputStream;
     12 
     13 /**
     14  * @author shendunyuan@scenetec.com
     15  * @date 2018/12/20
     16  */
     17 @Slf4j
     18 @Component
     19 public class FtpPoolTemplate extends FtpBaseTemplate {
     20 
     21     private GenericObjectPool<FTPClient> ftpClientPool;
     22 
     23     public FtpPoolTemplate(FtpClientFactory ftpClientFactory) {
     24         this.ftpClientPool = new GenericObjectPool<>(ftpClientFactory);
     25     }
     26 
     27     /**
     28      * 上传文件
     29      *
     30      * @param inputStream 文件流
     31      * @param remotePath 远程文件,必须包含文件名
     32      * @return 上传成功返回true, 否则返回false
     33      */
     34     @Override
     35     public boolean uploadFile(InputStream inputStream, String remotePath) {
     36         // 上传
     37         FTPClient client = null;
     38         try {
     39             // 从池中获取对象
     40             client = getFtpClient();
     41             // 上传
     42             return uploadHandle(client, inputStream, remotePath);
     43         } catch (Exception ex) {
     44             ex.printStackTrace();
     45             log.error("上传文件异常。");
     46         } finally {
     47             // 将对象放回池中
     48             if (client != null) {
     49                 ftpClientPool.returnObject(client);
     50             }
     51         }
     52         return false;
     53     }
     54 
     55     /**
     56      * 下载文件
     57      * @param remotePath 远程文件,必须包含文件名
     58      * @param outputStream 本地文件流
     59      * @return 下载成功返回true,否则返回false
     60      */
     61     @Override
     62     public boolean downloadFile(String remotePath, OutputStream outputStream) {
     63         // 下载
     64         FTPClient client = null;
     65         try {
     66             // 从池中获取对象
     67             client = getFtpClient();
     68             // 下载
     69             return downloadHandle(client, remotePath, outputStream);
     70         } catch (Exception ex) {
     71             ex.printStackTrace();
     72             log.error("下载文件异常。");
     73         } finally {
     74             if (client != null) {
     75                 ftpClientPool.returnObject(client);
     76             }
     77         }
     78         return false;
     79     }
     80 
     81     /**
     82      * 删除文件
     83      * @param remotePath 远程文件,必须包含文件名
     84      * @return 下载成功返回true,否则返回false
     85      */
     86     @Override
     87     public boolean deleFile(String remotePath) {
     88         FTPClient client = null;
     89         try {
     90             // 从池中获取对象
     91             client = getFtpClient();
     92             // 删除文件
     93             return deleteHandle(client, remotePath);
     94         } catch (Exception ex) {
     95             ex.printStackTrace();
     96             log.error("删除文件异常。");
     97         } finally {
     98             if (client != null) {
     99                 ftpClientPool.returnObject(client);
    100             }
    101         }
    102         return false;
    103     }
    104 
    105 
    106     /**
    107      * 验证连接是否成功
    108      * @return 连接登录成功返回true,否则返回false
    109      */
    110     private FTPClient getFtpClient () {
    111         FTPClient client = null;
    112         try {
    113             while (true) {
    114                 // 获取客户端
    115                 client = ftpClientPool.borrowObject();
    116                 // 验证客户端
    117                 if (client == null) {
    118                     continue;
    119                 } else {
    120                     if (!client.isConnected() || !FTPReply.isPositiveCompletion(client.getReplyCode())) {
    121                         ftpClientPool.invalidateObject(client);
    122                     } else {
    123                         break;
    124                     }
    125                 }
    126             }
    127         } catch (Exception ex) {
    128             ex.printStackTrace();
    129         }
    130         return client;
    131     }
    132 
    133 }
    View Code

    7、ftp部分依赖配置

     1 <dependencies>
     2         <dependency>
     3             <groupId>org.apache.commons</groupId>
     4             <artifactId>commons-lang3</artifactId>
     5             <version>3.7</version>
     6         </dependency>
     7         <dependency>
     8             <groupId>org.slf4j</groupId>
     9             <artifactId>slf4j-api</artifactId>
    10             <version>1.7.25</version>
    11         </dependency>
    12         <dependency>
    13             <groupId>commons-net</groupId>
    14             <artifactId>commons-net</artifactId>
    15             <version>3.3</version>
    16         </dependency>
    17         <dependency>
    18             <groupId>org.projectlombok</groupId>
    19             <artifactId>lombok</artifactId>
    20             <version>1.16.8</version>
    21             <scope>provided</scope>
    22         </dependency>
    23         <dependency>
    24             <groupId>org.apache.commons</groupId>
    25             <artifactId>commons-pool2</artifactId>
    26             <version>2.5.0</version>
    27         </dependency>
    28     </dependencies>
    View Code

    8、ftp测试类

     1 package com.scenetec.isv.operation.ftp;
     2 
     3 import com.scenetec.isv.operation.ISVOperationManagerApplication;
     4 import com.scenetec.isv.utils.ftp.template.FtpOnceTemplate;
     5 import com.scenetec.isv.utils.ftp.template.FtpPoolTemplate;
     6 import org.junit.Test;
     7 import org.junit.runner.RunWith;
     8 import org.springframework.beans.factory.annotation.Autowired;
     9 import org.springframework.boot.test.context.SpringBootTest;
    10 import org.springframework.test.context.junit4.SpringRunner;
    11 
    12 import javax.annotation.Resource;
    13 import java.io.File;
    14 
    15 /**
    16  * @author shendunyuan@scenetec.com
    17  * @date 2018/12/20
    18  */
    19 @SpringBootTest(classes = ISVOperationManagerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    20 @RunWith(SpringRunner.class)
    21 public class FtpClientPoolTest {
    22 
    23     @Autowired
    24     private FtpPoolTemplate ftpPoolTemplate;
    25     @Resource
    26     private FtpOnceTemplate ftpOnceTemplate;
    27 
    28     private String localPath = "/Users/sdy/test/isv/platform.cer";
    29     private String localDownPath = "/Users/sdy/test/isv/2019/111test.cer";
    30     private String remotePath = "/2019/111.cer";
    31 
    32     @Test
    33     public void upload() {
    34         boolean bool = ftpPoolTemplate.uploadFile(localPath, remotePath);
    35         if (bool) {
    36             System.out.println("success");
    37         } else {
    38             System.out.println("failed");
    39         }
    40     }
    41 
    42     @Test
    43     public void up() {
    44         boolean bool = ftpOnceTemplate.uploadFile(localPath, remotePath);
    45         if (bool) {
    46             System.out.println("success");
    47         } else {
    48             System.out.println("failed");
    49         }
    50     }
    51 
    52     @Test
    53     public void uploadFile() {
    54         File file = new File(localPath);
    55         boolean bool = ftpPoolTemplate.uploadFile(file, remotePath);
    56         if (bool) {
    57             System.out.println("success");
    58         } else {
    59             System.out.println("failed");
    60         }
    61     }
    62 
    63     @Test
    64     public void downloadFile() {
    65         boolean bool = ftpPoolTemplate.downloadFile(remotePath, localDownPath);
    66         if (bool) {
    67             System.out.println("success");
    68         } else {
    69             System.out.println("failed");
    70         }
    71     }
    72 
    73     @Test
    74     public void deleteFile() {
    75         boolean bool = ftpPoolTemplate.deleteFile(remotePath);
    76         if (bool) {
    77             System.out.println("success");
    78         } else {
    79             System.out.println("failed");
    80         }
    81     }
    82 }
    View Code

    注意:ftp多线程处理时容易超时,目前没有找到更好的处理办法。

    完整项目代码请参见:https://github.com/sxpdy8571/ftpUtils/tree/develop

  • 相关阅读:
    node.js抓取数据(fake小爬虫)
    认识mongoDB数据库
    node.js基础:数据存储
    mysql语句在node.js中的写法
    node.js基础:HTTP服务器
    node.js基础:模块的创建和引入
    认识node.js:express(一)
    认识Require
    认识Backbone (五)
    认识Backbone (四)
  • 原文地址:https://www.cnblogs.com/sxpdy8571/p/10263847.html
Copyright © 2011-2022 走看看