Java 实现FTP 和SFTP链接下载文件
并处理出现的org.apache.commons.net.MalformedServerReplyException: Could not parse response code.Server Reply: SSH-2.0-OpenSSH异常
由于项目中要从云服务器中获取实时的图片,故需要开发此功能,所以记录一下
我首先用的是
FTP链接
- 导入maven依赖commons-net
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
-
实现工具类 由于我只需要下载功能就实现下载
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; public class FileUtil { //ftp对象 private static FTPClient ftp; //需要连接到的ftp端的ip private String ip; //连接端口,默认21 private int port; //要连接到的ftp端的名字 private String name; //要连接到的ftp端的对应得密码 private String password; public ftp1(String ip, int port, String name, String password) { ftp = new FTPClient(); this.ip = ip; this.port = port; this.name = name; this.password = password; //验证登录 try { ftp.connect(ip, port); System.out.println(ftp.login(name, password)); ftp.setCharset(Charset.forName("UTF-8")); ftp.setControlEncoding("UTF-8"); System.out.println("链接成功"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //下载文件的第二种方法,优化了传输速度 public void getFile2() { try { InputStream is = ftp.retrieveFileStream("zhuye.html"); System.out.println("读取成功"); FileOutputStream fos = new FileOutputStream(new File("D:/zhuye.html")); byte[] b = new byte[1024]; int len = 0; while ((len = is.read(b)) != -1) { fos.write(b,0,len); } System.out.println("输出成功"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String args[]) { String ip="";//临时域名 String username="";//用户名 String password="";//密码 ftp1 m = new ftp1(ip,21,username,password); m.getFilesName(); } }
注:结果在登录时一直出错
org.apache.commons.net.MalformedServerReplyException: Could not parse response code. Server Reply: SSH-2.0-OpenSSH
报错原因
我的解决办法
使用 com.jcraft.jsch.ChannelSftp 代替org.apache.commons.net.ftp.FTPClient
SFTP链接
- 导入maven依赖com.jcraft
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
2.实现工具类
public class FileUtil {
//用户名
private String username;
//密码
private String password;
//ip
private String host;
//端口一般为22
private int port;
//私钥
private String privateKey;
ChannelSftp sftp = null;
//通过构造方法传参
public FileUtil(String username, String password, String host, int port){
this.username = username;
this.password = password;
this.host = host;
this.port = port;
}
public FileUtil(String username, String host, int port, String privateKey){
this.username = username;
this.host = host;
this.port = port;
this.privateKey = privateKey;
}
//登录,检查链接情况
public void login(){
try {
JSch jSch = new JSch();
if(privateKey != null){
jSch.addIdentity(privateKey);
}
Session session = jSch.getSession(username,host,port);
if(password != null){
session.setPassword(password);
}
session.setTimeout(100000);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
System.out.println("登录成功");
} catch (JSchException e) {
e.printStackTrace();
}
}
//上传文件
/**
* @param basePath 目标路径
* @param direcotry 目标子路径
* @param sftpFileName 文件名称
*/
public void upload(String basePath, String direcotry, String sftpFileName, InputStream inputStream) throws SftpException{
try {
//进入到目标目录
sftp.cd(basePath);
sftp.cd(direcotry);
} catch (SftpException e) {
String[] dirs = direcotry.split("/");
String temPath = basePath;
for (String dir: dirs
) {
if( null == dir || "".equals(dir)) continue;
temPath +="/" + dir;
try {
sftp.cd(temPath);
} catch (SftpException ex) {
sftp.mkdir(temPath);
sftp.cd(temPath);
}
}
}
sftp.put(inputStream,sftpFileName);
System.out.println("上传成功");
}
//下载文件
/**
* @param directory 下载的文件路径
* @param downloadFile 下载的文件名
* @param saveFileDirectory 保存的文件路径
*/
public void download(String directory, String downloadFile, String saveFileDirectory) throws SftpException, FileNotFoundException{
if(directory != null && !"".equals(directory)){
sftp.cd(directory);
}
String saveFile = saveFileDirectory + "//" + downloadFile;
File file = new File(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
System.out.println("下载成功");
}
//登出
public static void main(String[] args) throws FileNotFoundException,SftpException {
FileUtil fiel = new FileUtil("root","XXXXXX","112.74.109.XX",22);
fiel.login();
//测试上传功能
File file = new File("D:\\image\\1.jpg");
InputStream is = new FileInputStream(file);
fiel.upload("/usr/local/image","","1.jpg",is);
//测试下载功能
try {
fiel.download("/usr/local/image/","1.jpg","D:\\image");
} catch (SftpException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
总结
在登录服务器时卡了很久,没有搞清楚到底是SFTP还是FTP
接下来需要实现按时间下载文件夹下的每个图片