Java工具jsch.jar实现上传下载

时间:2021-11-06 13:52:38

在做运维的时候,我们一般使用shell脚本实现文件的服务器之间定时传输,那么对于一些不会shell脚本的童鞋,就得使用万能的编程语言了,这里我们介绍一款java操作ftp的工具,那就是jsch.jar。工具已经写好,可以根据实际情况做调整,注释很清晰。大家按需阅读:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
package com.wdy.tools.utils.sftputil;
 
import java.io.file;
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.inputstream;
import java.io.outputstream;
import java.util.arrays;
import java.util.collections;
import java.util.properties;
import java.util.vector;
 
import org.apache.commons.logging.log;
import org.apache.commons.logging.logfactory;
 
import com.jcraft.jsch.channel;
import com.jcraft.jsch.channelsftp;
import com.jcraft.jsch.jsch;
import com.jcraft.jsch.session;
 
/**
 * 利用jsch.jar针对sftp的上传和下载
 * 需要jar包:
 * commons-lang3-3.2.1.jar
 * commons-logging.jar
 * jsch-0.1.53.jar
 * log4j-1.2.17.jar
 * @author wangdy
 *
 */
public class jschsftputils {
 
 private static final log log = logfactory.getlog(jschsftputils.class);
 
 /**
 * 利用jsch包实现sftp下载文件
 * (这里是将serverpath下的指定扩展名的文件,全部下载到localpath下)
 * @param ip 主机ip
 * @param user 主机登陆用户名
 * @param psw 主机登陆密码
 * @param port 主机ssh2登陆端口,如果取默认值,传<=0的值,如-1
 * @param localpath 下载的本地目录的路径
 * @param serverpath 服务器目录
 * @param fileexetension 文件扩展名,格式如:'.txt'
 * @param isdelete 是否删除该路径下扩展名为fileexetension的远程文件
 * @throws exception
 */
 public static void sshsftpdownload(string ip, string user, string psw, int port, string serverpath, string localpath, string fileextension, boolean isdelete) throws exception {
 session session = null;
 channel channel = null;
 jsch jsch = new jsch();
 if (port <= 0) {
 // 连接服务器,采用默认端口
 session = jsch.getsession(user, ip);
 } else {
 // 采用指定的端口连接服务器
 session = jsch.getsession(user, ip, port);
 }
 // 如果服务器连接不上,则抛出异常
 if (session == null) {
 throw new exception("session is null");
 }
 // 设置登陆主机的密码
 session.setpassword(psw);// 设置密码
 // 设置第一次登陆的时候提示,可选值:(ask | yes | no)
// session.setconfig("stricthostkeychecking", "no");
 properties sshconfig = new properties();
 sshconfig.put("stricthostkeychecking", "no");
 session.setconfig(sshconfig);
 // 设置登陆超时时间ms
// session.connect(640);
 session.connect();
 log.info("session connected.");
 log.info("opening channel.");
 try {
 // 创建sftp通信通道
 channel = (channel) session.openchannel("sftp");
 channel.connect();
// channel.connect(1000);
 channelsftp sftp = (channelsftp) channel;
 log.info("connected to " + ip + ".");
 // 进入服务器指定的文件夹
 sftp.cd(serverpath);
 /**
 * 列出服务器指定的文件列表(可以加参数,指明要下载的文件类型)
 * 说明:如果fileextension不为空,则下载指定扩展名的文件集;
 * 如果fileextension为"",则下载该目录下所有类型的文件,如果是文件夹的话,会报错,如果您路径下有以.连接的文件夹,请注意,这是不可以的,程序会在过滤到该文件夹时中断
 */
 vector<?> v = null;
 if (fileextension != null && !"".equals(fileextension)) {
 v = sftp.ls("*"+fileextension);
 }else {
 try {
  v = sftp.ls("*.*");//ls -al | grep \"^-\"只显示文件---// ls -al | grep "^d"只显示目录包括.和..
 } catch (exception e) {
  log.info("您操作的是一个文件夹!");
 }
 }
 
 for (int i = 0; i < v.size(); i++) {
// log.info("fileinfos: "+v.get(i));
 string[] fileinfos = v.get(i).tostring().replaceall("\t", " ").split(" ");
 string filename = fileinfos[fileinfos.length-1];
 log.info("filename is: "+filename);
 // 以下代码实现从服务器下载一个文件到 本地
 inputstream instream = sftp.get(filename);
 outputstream outstream = new fileoutputstream(new file(localpath+"/"+filename));
 byte b[] = new byte[1024];
 int n;
 while ((n = instream.read(b)) != -1) {
  outstream.write(b, 0, n);
 }
 outstream.flush();
 outstream.close();
 instream.close();
 log.info("文件["+filename+"]下载成功!---->>>>下载到目录["+localpath+"]中.");
 //下载成功后,删除文件
 if (isdelete) {
  deleteonefile(serverpath, filename, sftp);
  log.info("文件["+filename+"]删除成功!");
 }
 }
 } catch (exception e) {
 e.printstacktrace();
 } finally {
 session.disconnect();
 channel.disconnect();
 }
 }
 
 /**
  * 利用jsch包实现sftp上传文件
  * @param ip 主机ip
  * @param user 主机登陆用户名
  * @param psw 主机登陆密码
  * @param port 主机ssh2登陆端口,如果取默认值,传<=0的值,如-1
  * @param localpath 本地目录
  * @param serverpath 服务器目录
  * @param fileextension 上传文件的扩展名 格式如:'.txt'
  */
 public static void sshsftpupload(string ip, string user, string psw, int port,string localpath, string serverpath, string fileextension) throws exception {
 session session = null;
 channel channel = null;
 jsch jsch = new jsch();
 if (port <= 0) {
 // 连接服务器,采用默认端口
 session = jsch.getsession(user, ip);
 } else {
 // 采用指定的端口连接服务器
 session = jsch.getsession(user, ip, port);
 }
 // 如果服务器连接不上,则抛出异常
 if (session == null) {
 log.info("session is null,服务器连接失败");
 throw new exception("session is null,服务器连接失败");
 }else {
 log.info("connected success, ip is ["+ip+"]");
 }
 // 设置登陆主机的密码
 session.setpassword(psw);// 设置密码
 // 设置第一次登陆的时候提示,可选值:(ask | yes | no)
 session.setconfig("stricthostkeychecking", "no");
 // 设置登陆超时时间ms
 session.connect(960);
 try {
 // 创建sftp通信通道
 channel = (channel) session.openchannel("sftp");
 channel.connect(1000);
 channelsftp sftp = (channelsftp) channel;
 // 进入服务器指定的文件夹
 sftp.cd(serverpath);
 // 列出服务器指定的文件列表
// vector v = sftp.ls("*.sh");
// for (int i = 0; i < v.size(); i++) {
// system.out.println(v.get(i));
// }
 // 以下代码实现从本地上传一个文件到服务器,如果要实现下载,对换一下流就可以了
 string[] files = getlocalfilenamearray(localpath);//获取所有文件名数组
 for (int i = 0; i < files.length; i++) {
 string filename = files[i];
 if (fileextension != null && !"".equals(fileextension)) {//如果扩展名不为空,则上传该路径下指定扩展名的文件
  if (filename.endswith(fileextension)) {
  outputstream outstream = sftp.put(filename);//要上传到服务器的文件,可以另外设个名字,也可以用本地的名称
  inputstream instream = new fileinputstream(new file(localpath+"/"+filename));//读取本地文件
  byte b[] = new byte[1024];
  int n;
  while ((n = instream.read(b)) != -1) {
  outstream.write(b, 0, n);
  }
  outstream.flush();
  outstream.close();
  instream.close();
  log.info("文件["+localpath+"/"+filename+"]上传成功!---->>>>上传到目录["+serverpath+"]中.");
  }else {
  log.info("警告:文件["+filename+"]不是指定类型["+fileextension+"]的文件");
  }
 }else {//如果扩展名为空,则上传该路径下的所有文件
  outputstream outstream = sftp.put(filename);//要上传到服务器的文件,可以另外设个名字,也可以用本地的名称
  inputstream instream = new fileinputstream(new file(localpath+"/"+filename));//本地文件
  byte b[] = new byte[1024];
  int n;
  while ((n = instream.read(b)) != -1) {
  outstream.write(b, 0, n);
  }
  outstream.flush();
  outstream.close();
  instream.close();
  log.info("文件["+filename+"]上传成功!---->>>>上传到目录["+serverpath+"]中.");
 }
 }
 } catch (exception e) {
 e.printstacktrace();
 } finally {
 session.disconnect();
 channel.disconnect();
 }
 }
 
 
 /**
  * 利用jsch包实现sftp下载、上传文件(该方法暂不适用)
  * @param ip 主机ip
  * @param user 主机登陆用户名
  * @param psw 主机登陆密码
  * @param port 主机ssh2登陆端口,如果取默认值(默认值22),传-1
  * @param privatekey 密钥文件路径
  * @param passphrase 密钥的密码
  *
  */
 public static void sshsftp(string ip, string user, string psw ,int port ,string privatekey ,string passphrase) throws exception{
  session session = null;
  channel channel = null;
  jsch jsch = new jsch();
  //设置密钥和密码
  if (privatekey != null && !"".equals(privatekey)) {
   if (passphrase != null && "".equals(passphrase)) {
    //设置带口令的密钥
    jsch.addidentity(privatekey, passphrase);
   } else {
    //设置不带口令的密钥
    jsch.addidentity(privatekey);
   }
  }
  if(port <=0){
   //连接服务器,采用默认端口
   session = jsch.getsession(user, ip);
  }else{
   //采用指定的端口连接服务器
   session = jsch.getsession(user, ip ,port);
  }
  //如果服务器连接不上,则抛出异常
  if (session == null) {
   throw new exception("session is null");
  }
  //设置登陆主机的密码
  session.setpassword(psw);//设置密码
  //设置第一次登陆的时候提示,可选值:(ask | yes | no)
  session.setconfig("stricthostkeychecking", "no");
  //设置登陆超时时间
  session.connect(30000);
  try {
   //创建sftp通信通道
   channel = (channel) session.openchannel("sftp");
   channel.connect(1000);
   channelsftp sftp = (channelsftp) channel;
   //进入服务器指定的文件夹
   sftp.cd("domains");
   //列出服务器指定的文件列表
   vector<?> v = sftp.ls("*.txt");
   for(int i=0;i<v.size();i++){
    log.info(v.get(i));
   }
   //以下代码实现从本地上传一个文件到服务器,如果要实现下载,对换以下流就可以了
   outputstream outstream = sftp.put("1.txt");
   inputstream instream = new fileinputstream(new file("c:/print.txt"));
   byte b[] = new byte[1024];
   int n;
   while ((n = instream.read(b)) != -1) {
    outstream.write(b, 0, n);
   }
   outstream.flush();
   outstream.close();
   instream.close();
  } catch (exception e) {
   e.printstacktrace();
  } finally {
   session.disconnect();
   channel.disconnect();
  }
 }
 
 
 //***************utils******************//
 /**
 * 读取指定路径下的所有文件
 * @param localpath 指定路径
 * @return string[] 文件名数组
 */
 public static string[] getlocalfilenamearray(string localpath){
 file diskfile = new file(localpath);
 string[] filenamelist = diskfile.list() ;
 if(filenamelist!=null){
 //按照文件名倒序排序
 arrays.sort(filenamelist,collections.reverseorder());
 }
 return filenamelist ;
 }
 
 
 /**
 * 删除指定目录的,指定扩展名的远程文件
 * @param directory 要删除文件的目录
 * @param sftp channelsftp实体
 * @param fileextension 文件扩展名(删除远程文件,扩展名不能为空)
 */
 public void deleteall(string directory, channelsftp sftp, string fileextension) {
  try {
  sftp.cd(directory);
  vector<?> v = null;
  if (fileextension !=null && "".equals(fileextension)) {
  v=sftp.ls("*"+fileextension);
 }else {
// v=sftp.ls("");//此处有风险
 log.warn("fileextension is not null! please check");
 }
  for (int i = 0; i < v.size(); i++) {
  string[] fileinfos = v.get(i).tostring().replaceall("\t", " ").split(" ");
 string filename = fileinfos[fileinfos.length-1];
   sftp.rm(filename);
  }
  } catch (exception e) {
  e.printstacktrace();
  }
 }
 
 /**
 * 删除单个文件
 *
 * @param directory
 *   要删除文件所在目录
 * @param deletefile
 *   要删除的文件
 * @throws exception 
 */
 public static void deleteonefile(string directory, string deletefile, channelsftp sftp) throws exception {
 sftp.cd(directory);
 sftp.rm(deletefile);
 }
 
 
}

这就是整个工具的内容了。

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

原文链接:https://blog.csdn.net/wdy_2099/article/details/72853363