在做運維的時候,我們一般使用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