开发中遇到的问题&解决方案(六)

329 阅读3分钟

「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战

前言

之前的项目里有用到FTP,需要使用FTP把图片及一些必要文件上传到第三方的FTP服务器上,所以会涉及FTP连接,创建用户,创建文件夹,文件上传等,项目里选用的还是hutool包装的FTP工具类,下面来看看这些功能的在hutool里是怎么包装的。

1.连接

1)init,配置参数FtpConfig包含主机、端口、用户名、密码及端口,和FtpMode包含主动模式和被动模式,所谓的主动和被动就是FTP的客户端上传文件到服务器端的动作是由人工主动上传还是由其他的事件触发后被动上传,下面是读取配置文件并初始化FTP连接的代码

public Ftp init(FtpConfig config, FtpMode mode) {
   final FTPClient client = new FTPClient();
   //是否需要开启验证功能,默认是不需要的
   client.setRemoteVerificationEnabled(false);
   //主要防止创建中文文件夹时发生乱码的问题 一般都是UTF-8 可以设置为默认的
   final Charset charset = config.getCharset();
   if (null != charset) {
      client.setControlEncoding(charset.toString());
   }
   //超时时间根据具体业务定
   client.setConnectTimeout((int) config.getConnectionTimeout());
   final String systemKey = config.getSystemKey();
   if (StrUtil.isNotBlank(systemKey)) {
      final FTPClientConfig conf = new FTPClientConfig(systemKey);
      final String serverLanguageCode = config.getServerLanguageCode();
      if (StrUtil.isNotBlank(serverLanguageCode)) {
         conf.setServerLanguageCode(config.getServerLanguageCode());
      }
      client.configure(conf);
   }
   try {
      // 连接ftp服务器
      client.connect(config.getHost(), config.getPort());
      client.setSoTimeout((int) config.getSoTimeout());
      // 登录ftp服务器
      client.login(config.getUser(), config.getPassword());
   } catch (IOException e) {
      throw new IORuntimeException(e);
   }
   // 是否成功登录服务器 这里可以根据返回进行业务处理 比如重新连接操作
   final int replyCode = client.getReplyCode(); 
   if (false == FTPReply.isPositiveCompletion(replyCode)) {
      try {
         client.disconnect();
      } catch (IOException e) {
      }
      //省略......
   }
   this.client = client;
   if (mode != null) {
      setMode(mode);
   }
   return this;
}

2.创建文件夹

1)这里一般都是先判断文件夹是否存在,不存在再创建新的文件夹,先调existFile方法然后再调mkdir方法

public boolean mkdir(String dir) throws IORuntimeException {
   try {
     //创建文件夹
      return this.client.makeDirectory(dir);
   } catch (IOException e) {
      throw new IORuntimeException(e);
   }
}

3.上传,上传部分其实很好理解,直接上代码

public boolean upload(String destPath, String fileName, InputStream fileStream) throws IORuntimeException {
   try {
      //BINARY_FILE_TYPE的值
      //1.destPath为null或""上传到当前路径 一般默认当前路径
      //2.destPath为相对路径则相对于当前路径的子路径
      //3.destPath为绝对路径则上传到此路径
      client.setFileType(FTPClient.BINARY_FILE_TYPE);
   } catch (IOException e) {
      throw new IORuntimeException(e);
   }
   String pwd = null;
   if (this.backToPwd) {
      pwd = pwd();
   }
   if (StrUtil.isNotBlank(destPath)) {
      //这里同样会进行文件夹是否存在 不存在即新建的判断
      mkDirs(destPath);
      if (false == isDir(destPath)) {
         throw new FtpException("Change dir to [{}] error, maybe dir not exist!", destPath);
      }
   }
   try {
      //保存文件到服务器
      return client.storeFile(fileName, fileStream);
   } catch (IOException e) {
      throw new IORuntimeException(e);
   } finally {
      if (this.backToPwd) {
         cd(pwd);
      }
   }
}

4.其他操作

1)cd(),切换路径,一般上传都是默认当前路径

2)ls(),遍历当前文件夹下的所有文件

3)lsFiles,遍历某个目录下所有文件和目录

4)stat(),当前文件夹的状态,可根据状态选择进行其他业务操作 上面这些命令是不是很有linux命令的味道,十分的通用

小结

开源软件给我们的开发确确实实带来很多快捷,复制粘贴就用,但是对于初学者来说并不好,就像现在的spring boot的开箱即用,很多人已经忘记了spring的一些配置和底层实现,这些只能说自己去把控吧,了解底层才能走得更远。