Java下载远程服务器文件到本地(基于http协议和ssh2协议)
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做很多事情,有兴趣的童鞋可以多了解。
另外在copyfile()方法的最后有一段注释的代码:
//sftp /*sftpv3client sftpclient = new sftpv3client(conn); sftpclient.createfile("files"); sftpclient.close();*/
我们也可以通过建立sftp连接来远程操作目录和文件,比如:创建、删除目录,创建、删除文件等。
关于ssh2包的其他功能和用法不再引申,有兴趣的童鞋欢迎在评论区交流。
以上就是java下载远程服务器文件到本地(基于http协议和ssh2协议)的详细内容,更多关于java 下载服务器文件的资料请关注其它相关文章!
上一篇: 解决PostgreSQL 执行超时的情况
下一篇: 支付宝商家二维码被调换怎么申请理赔