美文网首页
android 请求sftp服务器

android 请求sftp服务器

作者: Dirtykk | 来源:发表于2021-01-19 14:56 被阅读0次

            最近的项目上需要访问客户的sftp服务器,开发文件的上传和下载的功能,上网查询了相关知识点,中间也踩过不少坑,学到蛮多东西。

            参考链接:https://www.jianshu.com/p/05341634bae2

                              https://blog.csdn.net/ruixue0117/article/details/86517566

        1. 使用ftpClient进行处理

            刚开始在http的相关jar包中去找,发现android并没有官方提供的api方法调用,需要添加第三方jar包,这其中使用较多的就是 ftp4j 和common-net的包,后者属于java的基础包之一。这里我选择的是common-net的包,于是上网去查询,发现好多包的版本不一,而且都是需要积分的。这个时候突然想起,这种包应该在maven仓库中会有引入地址的。但是我突然忘记了maven官网的地址,这里安利一个网站叫 https://www.wanandroid.com/ 很适合学习安卓的小伙伴,我在这的入口找到了common-net的引用地址。

    jar包地址

            在gradle中添加远程依赖 implementation 'commons-net:commons-net:3.7.2',其中关键的一个类就是FtpClient,这个类中封装了请求ftp服务器的方法。具体使用过程可以参靠https://www.jianshu.com/p/05341634bae2,当我按照这个方法进行调试时,发现请求连接服务器失败,报错信息为 org.apache.commons.net.MalformedServerReplyException: Could not parse response code.Server Reply: SSH-2.0-OpenSSH_5.3 ,查询资料后得知,当使用org.apache.commons.net.ftp.FTPClient通过协议SSH2进行SFTP连接时报如上错误,原因是它不支持这种方式的连接(使用FTPSClient的SSL也是不行的)。

    2. 使用jsch访问sftp服务器

            common-net的包提供的方法不行,考虑是不是因为功能上有差异,于是转为使用ftp4j的jar包,引入方式也是采用gradle配置,引入之后发现核心处理类依旧是ftpclient,只是封装方式跟common-net有一些区别而已,既然是协议方面的问题,于是跟客户沟通发现其开通了sftp服务协议,那现在就应该是sftp的服务器了,那就不能用最基本的请求ftp的方法来处理 ,这里我使用的com.jcraft.jsch.JSch的类来进行处理。

        首先依旧是引入远程仓库地址 implementation'com.jcraft:jsch:0.1.55'  ,接下来便是封装相关的工具类,这里我把代码放上来,很简单的代码。

    private JSchjSch;     

    private Sessionsession =null;

    private ChannelSftpsftp =null;

    private SessionsshSession =null;

    private static SftpUtilssftpUtils =null;

    public SftpUtils() {

    jSch =new JSch();

    }

    public static SftpUtilsgetInstance(){

    if (sftpUtils==null){

    sftpUtils =new SftpUtils();

      }

    return  sftpUtils;

    }

    /*

    * 启动连接

    * */

    public void connect(){

    try {

    jSch.getSession(Constant.FTP_USERNAME,Constant.FTP_URL,22);

        sshSession =jSch.getSession(Constant.FTP_USERNAME,Constant.FTP_URL,22);

        sshSession.setPassword(Constant.FTP_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 (JSchException 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();

        }

    }

    }

    /*

    * 批量下载文件

    * */

    public ListbatchDownFile(){

    List filenames =new ArrayList();//本地已更新文件的路径集合

      String saveStoreFileName = SharedHelp.getString("saveStoreFileName","");

      String saveProductFileName = SharedHelp.getString("saveProductFileName","");

      boolean _flag =false;

      if (!isConnect()){

    connect();

        _flag =true;

      }

    try {

    Vector v = listFiles("inbound");

        if (v.size()>0){

    Iterator iterator = v.iterator();

          while (iterator.hasNext()){

    ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) iterator.next();

            SftpATTRS attrs = entry.getAttrs();

            if (!attrs.isDir()){

    boolean flag =false;

              String filename = entry.getFilename();

              if (filename.contains("store_fixture") && !filename.equals(saveStoreFileName) ){

    //ftp服务器上的文件跟本地文件不一致,启动更新

                String localFilePath = CommonUtils.getLocalFilePath(Constant.LOCAL_FILE_INBODUN)

    + File.separator + filename;

                  flag = downloadFile(Constant.FTP_FILE_DOWNLOAD_PATH,filename,localFilePath);

                  if (flag){

    SharedHelp.saveString("saveStoreFileName",filename);

                    filenames.add(localFilePath);

                  }

    }else if(filename.contains("stock_sku_loc") && !filename.equals(saveProductFileName)){

    String localFilePath = CommonUtils.getLocalFilePath(Constant.LOCAL_FILE_INBODUN)

    + File.separator + filename;

                flag = downloadFile(Constant.FTP_FILE_DOWNLOAD_PATH,filename, localFilePath);

                if (flag){

    SharedHelp.saveString("saveProductFileName",filename);

                  filenames.add(localFilePath);

                }

    }

    }

    }

    }

    }catch (SftpException e) {

    e.printStackTrace();

      }finally {

    if (_flag)

    disConnect();

      }

    return filenames;

    }

    /*

    * 下载单个文件

    * */

    public BooleandownloadFile(String remotePath,String remoteFileName,String localFilePath){

    FileOutputStream fieloutput =null;

      boolean _flag =false;

      try {

    if (!isConnect()){

    connect();

          _flag =true;

        }

    File file =new File(localFilePath);

        if (!file.exists()) {

    File dir =new File(file.getParent());

          dir.mkdirs();

          file.createNewFile();

        }

    fieloutput =new FileOutputStream(file);

        sftp.get(remotePath + File.separator + remoteFileName, fieloutput);

    return true;

      }catch (Exception e) {

    e.printStackTrace();

      }finally {

    if (null != fieloutput) {

    try {

    fieloutput.close();

          }catch (IOException e) {

    e.printStackTrace();

          }

    }

    if (_flag)

    disConnect();

      }

    return false;

    }

    /**

    * 上传单个文件

    *

    * @param remotePath:远程保存目录

    * @param remoteFileName:保存文件名

    * @return

    */

    public boolean uploadFile(FileInputStream fip, String remoteFileName, String remotePath) {

    boolean _flag =false;

      try {

    if (!isConnect()){

    connect();

          _flag =true;

        }

    createDir(remotePath);

        sftp.put(fip, remoteFileName);

    return true;

      }catch (SftpException e) {

    e.printStackTrace();

      }finally {

    if (fip !=null) {

    try {

    fip.close();

          }catch (IOException e) {

    e.printStackTrace();

          }

    }

    if (_flag)

    disConnect();

      }

    return false;

    }

    /**

    * 创建目录

    *

    * @param createpath

    * @return

    */

    public boolean createDir(String createpath) {

    boolean _flag =false;

      try {

    if (!isConnect()){

    connect();

          _flag =true;

        }

    if (isDirExist(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();

      }finally {

    if (_flag)

    disConnect();

      }

    return false;

    }

    /**

    * 判断目录是否存在

    *

    * @param directory

    * @return

    */

    public boolean isDirExist(String directory) {

    boolean isDirExistFlag =false;

      boolean _flag =false;

      try {

    if (!isConnect()){

    connect();

          _flag =true;

        }

    SftpATTRS sftpATTRS =sftp.lstat(directory);

        isDirExistFlag =true;

        return sftpATTRS.isDir();

      }catch (Exception e) {

    if (e.getMessage().toLowerCase().equals("no such file")) {

    isDirExistFlag =false;

        }

    }finally {

    if (_flag)

    disConnect();

      }

    return isDirExistFlag;

    }

    /**

    * 列出目录下的文件

    *

    * @param directory:要列出的目录

    * @return

    * @throws SftpException

    */

    public VectorlistFiles(String directory)throws SftpException {

    boolean _flag =false;

      if (!isConnect()){

    connect();

        _flag =true;

      }

    Vector ls =sftp.ls("/home/sftp/stockcount/" + directory);

      if (_flag)

    disConnect();

      return ls;

    }

    public boolean isConnect() {

    return (this.sftp !=null &&

    this.sftp.isConnected() &&

    this.sshSession !=null &&

    this.sshSession.isConnected());

    }

    其中Constant类引用的静态对象是一些服务器地址  用户名  密码等配置。建议开发此功能之前先在电脑上下载查看ftp服务器的客户端应用。这样调试数据比较方便,也方便验证功能是否完善。网上很多工具,我这里使用的是xftp7,使用起来很方便。

    xftp

            

    相关文章

      网友评论

          本文标题:android 请求sftp服务器

          本文链接:https://www.haomeiwen.com/subject/niwqzktx.html