由于项目中要从云服务器中获取实时的图片,故需要开发此功能,所以记录一下
我首先用的是
<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
百度后发现是Java后台是通过org.apache.commons.net.ftp.FTPClient 连接服务器,进行FTP操作
报错原因
我们使用FileZilla软件链接服务器(FTP或者SFTP)都是能够成功链接的。区别是链接的参数中
我仔细查看了FileZilla在链接时的ip为:sftp://112.74.109.xx
但是在Java后台使用org.apache.commons.net.ftp.FTPClient通过协议SSH2进行SFTP连接时就会报如上错误,原因是它不支持这种方式的连接(使用FTPSClient的SSL也是不行的)。
我的解决办法
使用 com.jcraft.jsch.ChannelSftp 代替org.apache.commons.net.ftp.FTPClient
<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
接下来需要实现按时间下载文件夹下的每个图片