Java(자바)
Java Jsch를 활용하여 파일 다운로드(Jsch sftp, Jsch download file)
마샤와 곰
2019. 10. 23. 08:34
jsch를 활용해서 파일을 다운로드를 하려면 체널을 연결 할 때 sftp로 연결을 하면 된다.
그리고 나서 연결된 체널을 ChannelSftp 라는 객체로 바꾸어주고 난 뒤에 일반 비지니스 로직을 실행하면 된다.
먼저 연결부분이다.
import java.io.File;
import java.io.InputStream;
import java.util.Vector;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class JschExec {
private String ADDRESS = "주소";
private int PORT = 22;
private String USERNAME = "아이디";
private String PASSWORD = "비밀번호";
private static Session session = null;
private static Channel channel = null;
private static ChannelExec channelExec = null;
private static ChannelSftp channelSftp = null;
private static final String PATHSEPARATOR = "/";
//세션 오픈 메소드
public boolean sshAccess() throws Exception {
JSch jsch = new JSch();
jsch.setKnownHosts("/etc/hosts"); //요기 요거!!
session = jsch.getSession(USERNAME, ADDRESS, PORT);
session.setPassword(PASSWORD);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
return true;
}
}
중간에 보면 setKnownHosts라는 메소드를 사용한 부분이 있는데..간혹 리눅스에서 아래 사진과 같은 오류를 내는 경우가 있다.
접속하는 이름(명칭, 도메인 또는 ip)을 찾지못하는 오류이므로 hosts 파일이(윈도우는 System폴더) 있는 곳을 지정해 주면된다. 만약 위 사진과 같은 오류가 발생하지 않는다면 해당 메소드는 주석처리해도 된다.
마지막으로 다운로드를 구현한 메소드 이다.
//파일 다운로드
public void recursiveFolderDownload(String sourcePath, String destinationPath) throws Exception {
channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp) channel;
Vector<ChannelSftp.LsEntry> fileAndFolderList = channelSftp.ls(sourcePath); // Let list of folder content
for (ChannelSftp.LsEntry item : fileAndFolderList) {
if (!item.getAttrs().isDir()) { // 파일체크
if (!(new File(destinationPath + PATHSEPARATOR + item.getFilename())).exists()
|| (item.getAttrs().getMTime() > Long
.valueOf(new File(destinationPath + PATHSEPARATOR + item.getFilename()).lastModified()
/ (long) 1000)
.intValue())) { // Download only if changed later.
new File(destinationPath + PATHSEPARATOR + item.getFilename());
channelSftp.get(sourcePath + PATHSEPARATOR + item.getFilename(),
destinationPath + PATHSEPARATOR + item.getFilename()); // 파일 다운로드 하기
}
} else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) {
new File(destinationPath + PATHSEPARATOR + item.getFilename()).mkdirs(); // Empty folder copy.
recursiveFolderDownload(sourcePath + PATHSEPARATOR + item.getFilename(),
destinationPath + PATHSEPARATOR + item.getFilename());
}
}
}
내용이 무지 많지만..맨 처음에 만든 sshAccess 메소드를 실행한 뒤에 연결된 세션을 sftp로 바꾸어 이후의 비지니스로직을 수직하는 내용이라 생각하면 될 것 같다.
최종 소스코드라인은 아래처럼 사용하면 된다.
import java.io.File;
import java.io.InputStream;
import java.util.Vector;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class JschExec {
private String ADDRESS = "주소";
private int PORT = 22;
private String USERNAME = "아이디";
private String PASSWORD = "비밀번호";
private static Session session = null;
private static Channel channel = null;
private static ChannelExec channelExec = null;
private static ChannelSftp channelSftp = null;
private static final String PATHSEPARATOR = "/";
//세션 오픈 메소드
public boolean sshAccess() throws Exception {
JSch jsch = new JSch();
jsch.setKnownHosts("/etc/hosts"); //요기 요거!!
session = jsch.getSession(USERNAME, ADDRESS, PORT);
session.setPassword(PASSWORD);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
return true;
}
//파일 다운로드
public void recursiveFolderDownload(String sourcePath, String destinationPath) throws Exception {
channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp) channel;
Vector<ChannelSftp.LsEntry> fileAndFolderList = channelSftp.ls(sourcePath); // Let list of folder content
for (ChannelSftp.LsEntry item : fileAndFolderList) {
if (!item.getAttrs().isDir()) { // 파일체크
if (!(new File(destinationPath + PATHSEPARATOR + item.getFilename())).exists()
|| (item.getAttrs().getMTime() > Long
.valueOf(new File(destinationPath + PATHSEPARATOR + item.getFilename()).lastModified()
/ (long) 1000)
.intValue())) { // Download only if changed later.
new File(destinationPath + PATHSEPARATOR + item.getFilename());
channelSftp.get(sourcePath + PATHSEPARATOR + item.getFilename(),
destinationPath + PATHSEPARATOR + item.getFilename()); // 파일 다운로드 하기
}
} else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) {
new File(destinationPath + PATHSEPARATOR + item.getFilename()).mkdirs(); // Empty folder copy.
recursiveFolderDownload(sourcePath + PATHSEPARATOR + item.getFilename(),
destinationPath + PATHSEPARATOR + item.getFilename());
}
}
}
}
반응형