欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java8实现FTP及SFTP文件上传下载

程序员文章站 2022-03-10 14:25:55
有网上的代码,也有自己的理解,代码备份  一般连接windows服务器使用ftp,连接linux服务器使用sftp。linux都是通过sftp上传文件,不需要额外安装,非要使用ftp的话,还得安装ft...

有网上的代码,也有自己的理解,代码备份

  一般连接windows服务器使用ftp,连接linux服务器使用sftp。linux都是通过sftp上传文件,不需要额外安装,非要使用ftp的话,还得安装ftp服务(虽然刚开始我就是这么干的)。

  另外就是jdk1.8和jdk1.7之前的方法有些不同,网上有很多jdk1.7之前的介绍,本篇是jdk1.8的

添加依赖jsch-0.1.54.jar

<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
  <groupid>com.jcraft</groupid>
  <artifactid>jsch</artifactid>
  <version>0.1.54</version>
</dependency>

ftp上传下载文件例子

import sun.net.ftp.ftpclient;
import sun.net.ftp.ftpprotocolexception;

import java.io.*;
import java.net.inetsocketaddress;
import java.net.socketaddress;

/**
 * java自带的api对ftp的操作
 */
public class test {
  private ftpclient ftpclient;

  test(){
     /*
    使用默认的端口号、用户名、密码以及根目录连接ftp服务器
     */
    this.connectserver("192.168.56.130", 21, "jiashubing", "123456", "/home/jiashubing/ftp/anonymous/");
  }

  public void connectserver(string ip, int port, string user, string password, string path) {
    try {
      /* ******连接服务器的两种方法*******/
      ftpclient = ftpclient.create();
      try {
        socketaddress addr = new inetsocketaddress(ip, port);
        ftpclient.connect(addr);
        ftpclient.login(user, password.tochararray());
        system.out.println("login success!");
        if (path.length() != 0) {
          //把远程系统上的目录切换到参数path所指定的目录
          ftpclient.changedirectory(path);
        }
      } catch (ftpprotocolexception e) {
        e.printstacktrace();
      }
    } catch (ioexception ex) {
      ex.printstacktrace();
      throw new runtimeexception(ex);
    }
  }

  /**
   * 关闭连接
   */
  public void closeconnect() {
    try {
      ftpclient.close();
      system.out.println("disconnect success");
    } catch (ioexception ex) {
      system.out.println("not disconnect");
      ex.printstacktrace();
      throw new runtimeexception(ex);
    }
  }

  /**
   * 上传文件
   * @param localfile 本地文件
   * @param remotefile 远程文件
   */
  public void upload(string localfile, string remotefile) {
    file file_in = new file(localfile);
    try(outputstream os = ftpclient.putfilestream(remotefile);
      fileinputstream is = new fileinputstream(file_in)) {
      byte[] bytes = new byte[1024];
      int c;
      while ((c = is.read(bytes)) != -1) {
        os.write(bytes, 0, c);
      }
      system.out.println("upload success");
    } catch (ioexception ex) {
      system.out.println("not upload");
      ex.printstacktrace();
    } catch (ftpprotocolexception e) {
      e.printstacktrace();
    }
  }

  /**
   * 下载文件。获取远程机器上的文件filename,借助telnetinputstream把该文件传送到本地。
   * @param remotefile 远程文件路径(服务器端)
   * @param localfile 本地文件路径(客户端)
   */
  public void download(string remotefile, string localfile) {
    file file_in = new file(localfile);
    try(inputstream is = ftpclient.getfilestream(remotefile);
      fileoutputstream os = new fileoutputstream(file_in)){

      byte[] bytes = new byte[1024];
      int c;
      while ((c = is.read(bytes)) != -1) {
        os.write(bytes, 0, c);
      }
      system.out.println("download success");
    } catch (ioexception ex) {
      system.out.println("not download");
      ex.printstacktrace();
    }catch (ftpprotocolexception e) {
      e.printstacktrace();
    }
  }

  public static void main(string agrs[]) {
    test fu = new test();

    //下载测试
    string filepath[] = {"aa.xlsx","bb.xlsx"};
    string localfilepath[] = {"e:/lalala/aa.xlsx","e:/lalala/bb.xlsx"};
    for (int i = 0; i < filepath.length; i++) {
      fu.download(filepath[i], localfilepath[i]);
    }
    //上传测试
    string localfile = "e:/lalala/tt.xlsx";
    string remotefile = "tt.xlsx";        //上传
    fu.upload(localfile, remotefile);
    fu.closeconnect();
  }
}

sftp上传下载文件例子

import com.jcraft.jsch.*;

import java.util.properties;

/**
 * 解释一下sftp的整个调用过程,这个过程就是通过ip、port、username、password获取一个session,
 * 然后通过session打开sftp通道(获得sftp channel对象),再在建立通道(channel)连接,最后我们就是
 * 通过这个channel对象来调用sftp的各种操作方法.总是要记得,我们操作完sftp需要手动断开channel连接与session连接。
 * @author jiashubing
 * @since 2018/5/8
 */
public class sftpcustom {

  private channelsftp channel;
  private session session;
  private string sftppath;

  sftpcustom() {
     /*
     使用端口号、用户名、密码以连接sftp服务器
     */
    this.connectserver("192.168.56.130", 22, "jiashubing", "123456", "/home/ftp/");
  }

  sftpcustom(string ftphost, int ftpport, string ftpusername, string ftppassword, string sftppath) {
    this.connectserver(ftphost, ftpport, ftpusername, ftppassword, sftppath);
  }

  public void connectserver(string ftphost, int ftpport, string ftpusername, string ftppassword, string sftppath) {
    try {
      this.sftppath = sftppath;

      // 创建jsch对象
      jsch jsch = new jsch();
      // 根据用户名,主机ip,端口获取一个session对象
      session = jsch.getsession(ftpusername, ftphost, ftpport);
      if (ftppassword != null) {
        // 设置密码
        session.setpassword(ftppassword);
      }
      properties configtemp = new properties();
      configtemp.put("stricthostkeychecking", "no");
      // 为session对象设置properties
      session.setconfig(configtemp);
      // 设置timeout时间
      session.settimeout(60000);
      session.connect();
      // 通过session建立链接
      // 打开sftp通道
      channel = (channelsftp) session.openchannel("sftp");
      // 建立sftp通道的连接
      channel.connect();
    } catch (jschexception e) {
      //throw new runtimeexception(e);
    }
  }

  /**
   * 断开sftp channel、session连接
   */
  public void closechannel() {
    try {
      if (channel != null) {
        channel.disconnect();
      }
      if (session != null) {
        session.disconnect();
      }
    } catch (exception e) {
      //
    }
  }

  /**
   * 上传文件
   *
   * @param localfile 本地文件
   * @param remotefile 远程文件
   */
  public void upload(string localfile, string remotefile) {
    try {
      remotefile = sftppath + remotefile;
      channel.put(localfile, remotefile, channelsftp.overwrite);
      channel.quit();
    } catch (sftpexception e) {
      //e.printstacktrace();
    }
  }

  /**
   * 下载文件
   *
   * @param remotefile 远程文件
   * @param localfile 本地文件
   */
  public void download(string remotefile, string localfile) {
    try {
      remotefile = sftppath + remotefile;
      channel.get(remotefile, localfile);
      channel.quit();
    } catch (sftpexception e) {
      //e.printstacktrace();
    }
  }

  public static void main(string[] args) {
    sftpcustom sftpcustom = new sftpcustom();
    //上传测试
    string localfile = "e:/lalala/tt.xlsx";
    string remotefile = "/home/ftp/tt2.xlsx";
    sftpcustom.upload(localfile, remotefile);
    //下载测试
    sftpcustom.download(remotefile, "e:/lalala/tt3.xlsx");
    sftpcustom.closechannel();
  }
}

jsch-0.1.54.jar 学习了解

channelsftp类是jsch实现sftp核心类,它包含了所有sftp的方法,如:

  文件上传put(),
  文件下载get(),
  进入指定目录cd().
  得到指定目录下的文件列表ls().
  重命名指定文件或目录rename().
  删除指定文件rm(),创建目录mkdir(),删除目录rmdir().

大家引用方法时可以快速参考一下,具体传参需参考源码~

最后还要提一下的就是jsch支持的三种文件传输模式:

  ● append 追加模式,如果目标文件已存在,传输的文件将在目标文件后追加。

  ● resume 恢复模式,如果文件已经传输一部分,这时由于网络或其他任何原因导致文件传输中断,如果下一次传输相同的文件,则会从上一次中断的地方续传。

  ● overwrite 完全覆盖模式,这是jsch的默认文件传输模式,即如果目标文件已经存在,传输的文件将完全覆盖目标文件,产生新的文件。

ftp和sftp区别

  ftp是一种文件传输协议,一般是为了方便数据共享的。包括一个ftp服务器和多个ftp客户端。ftp客户端通过ftp协议在服务器上下载资源。而sftp协议是在ftp的基础上对数据进行加密,使得传输的数据相对来说更安全。但是这种安全是以牺牲效率为代价的,也就是说sftp的传输效率比ftp要低(不过现实使用当中,没有发现多大差别)。个人肤浅的认为就是:一;ftp要安装,sftp不要安装。二;sftp更安全,但更安全带来副作用就是的效率比ftp要低些。

建议使用sftp代替ftp。

主要因为:

  1、可以不用额外安装任何服务器端程序

  2、会更省系统资源。

  3、sftp使用加密传输认证信息和传输数据,相对来说会更安全。

  4、也不需要单独配置,对新手来说比较简单(开启ssh默认就开启了sftp)。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。