Linux操作系统我们经常使用ssh中的ftp,sftp连接服务器,做相应操作。
如何通过java代码的形式采用sftp连接到服务器,进行文件上传下载等操作呢?
第一步,引入依赖包
1<!-- sftp上传依赖包 --> 2<dependency> 3 <groupId>com.jcraft</groupId> 4 <artifactId>jsch</artifactId> 5 <version>0.1.53</version> 6</dependency>
jsch常用密码登陆和密钥认证的形式进行sftp服务器登陆。
第二步,编写工具类,并采用main方法进行上传测试,代码如下
1package com.guohuai.util; 2 3import java.io.ByteArrayInputStream; 4import java.io.File; 5import java.io.FileInputStream; 6import java.io.FileNotFoundException; 7import java.io.FileOutputStream; 8import java.io.IOException; 9import java.io.InputStream; 10import java.io.UnsupportedEncodingException; 11import java.util.Properties; 12import java.util.Vector; 13 14import org.apache.commons.io.IOUtils; 15import org.slf4j.Logger; 16import org.slf4j.LoggerFactory; 17 18import com.jcraft.jsch.Channel; 19import com.jcraft.jsch.ChannelSftp; 20import com.jcraft.jsch.JSch; 21import com.jcraft.jsch.JSchException; 22import com.jcraft.jsch.Session; 23import com.jcraft.jsch.SftpException; 24/** 25 * 26 * @ClassName: SFTPUtil 27 * @Description: sftp连接工具类 28 * @date 2017年5月22日 下午11:17:21 29 * @version 1.0.0 30 */ 31public class SFTPUtil { 32 private transient Logger log = LoggerFactory.getLogger(this.getClass()); 33 34 private ChannelSftp sftp; 35 36 private Session session; 37 /** FTP 登录用户名*/ 38 private String username; 39 /** FTP 登录密码*/ 40 private String password; 41 /** 私钥 */ 42 private String privateKey; 43 /** FTP 服务器地址IP地址*/ 44 private String host; 45 /** FTP 端口*/ 46 private int port; 47 48 49 /** 50 * 构造基于密码认证的sftp对象 51 * @param userName 52 * @param password 53 * @param host 54 * @param port 55 */ 56 public SFTPUtil(String username, String password, String host, int port) { 57 this.username = username; 58 this.password = password; 59 this.host = host; 60 this.port = port; 61 } 62 63 /** 64 * 构造基于秘钥认证的sftp对象 65 * @param userName 66 * @param host 67 * @param port 68 * @param privateKey 69 */ 70 public SFTPUtil(String username, String host, int port, String privateKey) { 71 this.username = username; 72 this.host = host; 73 this.port = port; 74 this.privateKey = privateKey; 75 } 76 77 public SFTPUtil(){} 78 79 /** 80 * 连接sftp服务器 81 * 82 * @throws Exception 83 */ 84 public void login(){ 85 try { 86 JSch jsch = new JSch(); 87 if (privateKey != null) { 88 jsch.addIdentity(privateKey);// 设置私钥 89 log.info("sftp connect,path of private key file:{}" , privateKey); 90 } 91 log.info("sftp connect by host:{} username:{}",host,username); 92 93 session = jsch.getSession(username, host, port); 94 log.info("Session is build"); 95 if (password != null) { 96 session.setPassword(password); 97 } 98 Properties config = new Properties(); 99 config.put("StrictHostKeyChecking", "no"); 100 101 session.setConfig(config); 102 session.connect(); 103 log.info("Session is connected"); 104 105 Channel channel = session.openChannel("sftp"); 106 channel.connect(); 107 log.info("channel is connected"); 108 109 sftp = (ChannelSftp) channel; 110 log.info(String.format("sftp server host:[%s] port:[%s] is connect successfull", host, port)); 111 } catch (JSchException e) { 112 log.error("Cannot connect to specified sftp server : {}:{} \n Exception message is: {}", new Object[]{host, port, e.getMessage()}); 113 } 114 } 115 116 /** 117 * 关闭连接 server 118 */ 119 public void logout(){ 120 if (sftp != null) { 121 if (sftp.isConnected()) { 122 sftp.disconnect(); 123 log.info("sftp is closed already"); 124 } 125 } 126 if (session != null) { 127 if (session.isConnected()) { 128 session.disconnect(); 129 log.info("sshSession is closed already"); 130 } 131 } 132 } 133 134 /** 135 * 将输入流的数据上传到sftp作为文件 136 * 137 * @param directory 138 * 上传到该目录 139 * @param sftpFileName 140 * sftp端文件名 141 * @param in 142 * 输入流 143 * @throws SftpException 144 * @throws Exception 145 */ 146 public void upload(String directory, String sftpFileName, InputStream input) throws SftpException{ 147 try { 148 sftp.cd(directory); 149 } catch (SftpException e) { 150 log.warn("directory is not exist"); 151 sftp.mkdir(directory); 152 sftp.cd(directory); 153 } 154 sftp.put(input, sftpFileName); 155 log.info("file:{} is upload successful" , sftpFileName); 156 } 157 158 /** 159 * 上传单个文件 160 * 161 * @param directory 162 * 上传到sftp目录 163 * @param uploadFile 164 * 要上传的文件,包括路径 165 * @throws FileNotFoundException 166 * @throws SftpException 167 * @throws Exception 168 */ 169 public void upload(String directory, String uploadFile) throws FileNotFoundException, SftpException{ 170 File file = new File(uploadFile); 171 upload(directory, file.getName(), new FileInputStream(file)); 172 } 173 174 /** 175 * 将byte[]上传到sftp,作为文件。注意:从String生成byte[]是,要指定字符集。 176 * 177 * @param directory 178 * 上传到sftp目录 179 * @param sftpFileName 180 * 文件在sftp端的命名 181 * @param byteArr 182 * 要上传的字节数组 183 * @throws SftpException 184 * @throws Exception 185 */ 186 public void upload(String directory, String sftpFileName, byte[] byteArr) throws SftpException{ 187 upload(directory, sftpFileName, new ByteArrayInputStream(byteArr)); 188 } 189 190 /** 191 * 将字符串按照指定的字符编码上传到sftp 192 * 193 * @param directory 194 * 上传到sftp目录 195 * @param sftpFileName 196 * 文件在sftp端的命名 197 * @param dataStr 198 * 待上传的数据 199 * @param charsetName 200 * sftp上的文件,按该字符编码保存 201 * @throws UnsupportedEncodingException 202 * @throws SftpException 203 * @throws Exception 204 */ 205 public void upload(String directory, String sftpFileName, String dataStr, String charsetName) throws UnsupportedEncodingException, SftpException{ 206 upload(directory, sftpFileName, new ByteArrayInputStream(dataStr.getBytes(charsetName))); 207 } 208 209 /** 210 * 下载文件 211 * 212 * @param directory 213 * 下载目录 214 * @param downloadFile 215 * 下载的文件 216 * @param saveFile 217 * 存在本地的路径 218 * @throws SftpException 219 * @throws FileNotFoundException 220 * @throws Exception 221 */ 222 public void download(String directory, String downloadFile, String saveFile) throws SftpException, FileNotFoundException{ 223 if (directory != null && !"".equals(directory)) { 224 sftp.cd(directory); 225 } 226 File file = new File(saveFile); 227 sftp.get(downloadFile, new FileOutputStream(file)); 228 log.info("file:{} is download successful" , downloadFile); 229 } 230 /** 231 * 下载文件 232 * @param directory 下载目录 233 * @param downloadFile 下载的文件名 234 * @return 字节数组 235 * @throws SftpException 236 * @throws IOException 237 * @throws Exception 238 */ 239 public byte[] download(String directory, String downloadFile) throws SftpException, IOException{ 240 if (directory != null && !"".equals(directory)) { 241 sftp.cd(directory); 242 } 243 InputStream is = sftp.get(downloadFile); 244 245 byte[] fileData = IOUtils.toByteArray(is); 246 247 log.info("file:{} is download successful" , downloadFile); 248 return fileData; 249 } 250 251 /** 252 * 删除文件 253 * 254 * @param directory 255 * 要删除文件所在目录 256 * @param deleteFile 257 * 要删除的文件 258 * @throws SftpException 259 * @throws Exception 260 */ 261 public void delete(String directory, String deleteFile) throws SftpException{ 262 sftp.cd(directory); 263 sftp.rm(deleteFile); 264 } 265 266 /** 267 * 列出目录下的文件 268 * 269 * @param directory 270 * 要列出的目录 271 * @param sftp 272 * @return 273 * @throws SftpException 274 */ 275 public Vector<?> listFiles(String directory) throws SftpException { 276 return sftp.ls(directory); 277 } 278 279 public static void main(String[] args) throws SftpException, IOException { 280 SFTPUtil sftp = new SFTPUtil("lanhuigu", "123456", "192.168.200.12", 22); 281 sftp.login(); 282 //byte[] buff = sftp.download("/opt", "start.sh"); 283 //System.out.println(Arrays.toString(buff)); 284 File file = new File("D:\\upload\\index.html"); 285 InputStream is = new FileInputStream(file); 286 287 sftp.upload("/data/work", "test_sftp_upload.csv", is); 288 sftp.logout(); 289 } 290}