Java下载远程服务器文件到本地(基于http协议和ssh2协议)

作者:胜金 时间:2022-08-29 12:23:18 

Java中java.io包为我们提供了输入流和输出流,对文件的读写基本上都依赖于这些封装好的关于流的类中来实现。前段时间遇到了以下两种需求:

1、与某系统对接,每天获取最新的图片并显示在前端页面。该系统提供的是一个http协议的图片URL,本来获取到该系统的图片地址以后在HTML中显示就可以了,但是该系统不太稳定,图片URL经常不能使用,而且每天生成图片不一定成功,

对自己系统的功能影响很大,emm。。。所以就考虑每天从该系统下载最新的图片到本地更新保存,没有新图片就继续使用上次的图片。

2、公司算法团队的同事完成了一个视频分析的检测功能,会生成一些截取的短视频文件,系统需要获取并保存这些视频文件。算法运行在Linux系统,没有搭建FTP服务器,所以就需要系统从运行算法的Linux系统复制文件到系统本地保存起来。

这两个需求实现起来都是大同小异,思路就是读取文件然后写到指定路径,只不过http协议的图片地址可以直接读取然后保存,而Linux系统的文件需要远程连接到该服务器然后再下载文件,这就需要我们引入以下依赖:


<!--远程读取服务器文件-->
<dependency>
 <groupId>ch.ethz.ganymed</groupId>
 <artifactId>ganymed-ssh2</artifactId>
 <version>262</version>
</dependency>
<dependency>
 <groupId>com.jcraft</groupId>
 <artifactId>jsch</artifactId>
 <version>0.1.53</version>
</dependency>
<dependency>
 <groupId>commons-net</groupId>
 <artifactId>commons-net</artifactId>
 <version>3.4</version>
</dependency>

废话不说了,先上代码:


package com.XXX.utils;

import ch.ethz.ssh2.*;
import com.databus.Log;
import com.mysql.jdbc.StringUtils;

import java.io.*;
import java.net.*;

public class FileUtils {

public static boolean downloadFile(String urlString,String fileName,String filePath) {
 boolean bool = false;

InputStream is = null;
 FileOutputStream os = null;
 try {
  Log.info("文件路径:" + urlString);
  // 构造URL
  java.net.URL url = new java.net.URL(urlString);
  // 打开连接
  URLConnection con = url.openConnection();
  // 输入流
  is = con.getInputStream();
  // 1K的数据缓冲
  byte[] bs = new byte[1024];
  // 读取到的数据长度
  int len;
  //判断指定目录是否存在,不存在则先创建目录
  File file = new File(filePath);
  if (!file.exists())
   file.mkdirs();
  //fileName如果不包含文件后缀,则需要加上后缀,如:fileName + ".jpg";fileName + ".txt";
  os = new FileOutputStream(filePath + fileName, false);//false:覆盖文件,true:在原有文件后追加
  // 开始读取
  while ((len = is.read(bs)) != -1) {
   os.write(bs, 0, len);
  }

bool = true;
  Log.info("文件保存成功:" + fileName);
 }catch (Exception e){
  e.printStackTrace();
 }finally {
  // 完毕,关闭所有链接
  if (null != os){
   try {
    os.flush();
    os.close();
   }catch (IOException e){
    e.printStackTrace();
   }
  }
  if (null != is){
   try {
    is.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 return bool;
}

//远程下载服务器文件
public static boolean copyFile(String ip,int port,String userName,String password,String sourceFile,String targetFile,String targetFileName){
 boolean bool = false;
 Connection conn = null;
 Session session = null;
 try {
  if (StringUtils.isNullOrEmpty(ip) || StringUtils.isNullOrEmpty(userName) || StringUtils.isNullOrEmpty(password) ||
    StringUtils.isNullOrEmpty(sourceFile) || StringUtils.isNullOrEmpty(targetFile)){
   return bool;
  }
  conn = new Connection(ip,port);
  conn.connect();
  boolean isAuth = conn.authenticateWithPassword(userName,password);
  if (!isAuth){
   Log.info("算法主机连接失败");
   return bool;
  }
  //执行命令
  session = conn.openSession();

//执行命令并打印执行结果
  session.execCommand("df -h");
  InputStream staout = new StreamGobbler(session.getStdout());
  BufferedReader br = new BufferedReader(new InputStreamReader(staout));
  String line = null;
  while ((line = br.readLine()) != null){
   System.out.println(line);
  }
  br.close();

//下载文件到本地
  SCPClient scpClient = conn.createSCPClient();
  SCPInputStream scpis = scpClient.get(sourceFile);

//判断指定目录是否存在,不存在则先创建目录
  File file = new File(targetFile);
  if (!file.exists())
   file.mkdirs();

FileOutputStream fos = new FileOutputStream(targetFile + targetFileName);
  byte[] buffer = new byte[1024];
  int len = 0;
  while ((len = scpis.read(buffer)) != -1){
   fos.write(buffer,0,len);
  }
  fos.close();
  bool = true;
  //SFTP
  /*SFTPv3Client sftPClient = new SFTPv3Client(conn);
  sftPClient.createFile("");
  sftPClient.close();*/
 }catch (Exception e){
  e.printStackTrace();
  Log.info(e.getMessage());
  Log.info("保存失败:" + sourceFile);
 }finally {
  if (null != session){
   session.close();
  }
  if (null != conn) {
   conn.close();
  }
 }

return bool;
}

}

第一个方法downloadFile(String urlString,String fileName,String filePath)与我们读写文件没什么区别,我们主要说一下远程读取Linux服务器文件的方法:

copyFile(String ip,int port,String userName,String password,String sourceFile,String targetFile,String targetFileName)
可以看到,我们需要Linux服务器的ip、ssh开放的端口号(一般默认是22)、服务器用户名和密码,所以我们要确保Linux服务器已经开放ssh连接,否则我们的程序根本就连不上服务器,更不要说复制文件了。

其实ssh2连接远程服务器,就和我们用Xshell连接服务器是一样的,不但可以复制文件,也可以执行Linux命令对Linux进行操作,看上面的一段代码:


//执行命令
 session = conn.openSession();

//执行命令并打印执行结果
 session.execCommand("df -h");
 InputStream staout = new StreamGobbler(session.getStdout());
 BufferedReader br = new BufferedReader(new InputStreamReader(staout));
 String line = null;
 while ((line = br.readLine()) != null){
 System.out.println(line);
 }
 br.close();

这段代码与复制文件没有关系,之所以保留就是要说明一下,我们执行了df -h 命令(查询服务器磁盘使用情况),将会得到磁盘的具体使用情况,与下图效果相同。所以我们可以用ssh2做很多事情,有兴趣的童鞋可以多了解。

Java下载远程服务器文件到本地(基于http协议和ssh2协议)

 另外在copyFile()方法的最后有一段注释的代码:


//SFTP
 /*SFTPv3Client sftPClient = new SFTPv3Client(conn);
 sftPClient.createFile("files");
 sftPClient.close();*/

我们也可以通过建立SFTP连接来远程操作目录和文件,比如:创建、删除目录,创建、删除文件等。

关于ssh2包的其他功能和用法不再引申,有兴趣的童鞋欢迎在评论区交流。

来源:https://www.cnblogs.com/JohanChan/p/14282163.html

标签:java,下载文件,服务器,本地,http协议,ssh2协议
0
投稿

猜你喜欢

  • Android实现多线程断点下载

    2023-08-11 00:45:28
  • android studio生成aar包并在其他工程引用aar包的方法

    2021-07-23 21:28:30
  • 基于@GetMapping注解携带参数的方式

    2023-01-26 20:49:32
  • 详解Java 中 RMI 的使用

    2023-10-12 08:31:27
  • Java构建JDBC应用程序的实例操作

    2023-08-07 12:09:13
  • java针对电话号码正则匹配实例

    2023-07-15 05:49:32
  • android客户端从服务器端获取json数据并解析的实现代码

    2023-09-30 07:52:20
  • 解读classpath读取resources目录下的文件

    2023-01-25 05:49:36
  • 利用Flutter实现“孔雀开屏”的动画效果

    2021-11-04 21:24:17
  • java日期工具类实例分享

    2023-05-17 17:50:40
  • Java 根据某个 key 加锁的实现方式

    2023-10-27 07:54:20
  • java将一个目录下的所有数据复制到另一个目录下

    2023-01-08 15:11:44
  • SpringBoot解决BigDecimal传到前端后精度丢失问题

    2021-12-13 14:44:39
  • Android的ListView多选删除操作实现代码

    2023-06-25 22:24:38
  • C# 判断字符串第一位是否为数字

    2023-05-29 20:06:44
  • Windows下RabbitMQ安装及配置详解

    2022-04-29 08:11:18
  • java字符串常用操作方法(查找、截取、分割)

    2023-11-29 03:21:13
  • C语言运算符及其优先级汇总表口诀

    2021-12-12 21:14:27
  • Unity实现简易日志输出功能

    2023-07-25 22:59:44
  • Android App获取屏幕旋转角度的方法

    2021-12-26 10:42:19
  • asp之家 软件编程 m.aspxhome.com