Java SFTP Using Jsch - 자바로 SFTP 파일 업로드/다운로드 개발
안녕하세요 최근에 정산관련해서 실적 파일을 업로드 및 다운로드 해야할 필요가 생겨서
해당 기능을 데몬으로 구현을 하였는데요
apache-commons에 있는 ftp/telnet 라이브러리로는 sftp/ssh 클라이언트를 구현할 수 없습니다.
jsch 라이브러리를 사용하면, sftp/ssh 클라이언트를 직접 구현할 수 있습니다.
jsch 라이브러리는 아래 url에 접속하시어서 다운로드 하시면 됩니다.
http://www.jcraft.com/jsch/
다운로드를 받으면 라이브러리에 추가를 하고
아래와 같이 만들고자 하는 모듈에 import를 해주시면 됩니다.
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
아래는 접속 예제입니다.
저는 모든 Method들의 Exception을 throws하여 해당 Method를 호출하는 곳에서 일괄적으로 처리하도록 하였습니다.
public void connect() throws JSchException {
System.out.println("connecting..."+host);
// 1. JSch 객체를 생성한다.
jsch = new JSch();
// 2. 세션 객체를 생성한다(사용자 이름, 접속할 호스트, 포트를 인자로 전달한다.)
session = jsch.getSession(user, host,port);
// 4. 세션과 관련된 정보를 설정한다.
session.setConfig("StrictHostKeyChecking", "no");
// 4. 패스워드를 설정한다.
session.setPassword(password);
// 5. 접속한다.
session.connect();
// 6. sftp 채널을 연다.
channel = session.openChannel("sftp");
// 7. 채널에 연결한다.
channel.connect();
// 8. 채널을 FTP용 채널 객체로 캐스팅한다.
sftpChannel = (ChannelSftp) channel;
}
접속을 해제하는 부분입니다.
public void disconnect() {
if(session.isConnected()){
System.out.println("disconnecting...");
sftpChannel.disconnect();
channel.disconnect();
session.disconnect();
}
}
파일을 업로드 하는 부분입니다.
public void upload(String fileName, String remoteDir) throws Exception {
FileInputStream fis = null;
// 앞서 만든 접속 메서드를 사용해 접속한다.
connect();
try {
// Change to output directory
sftpChannel.cd(remoteDir);
// Upload file
File file = new File(fileName);
// 입력 파일을 가져온다.
fis = new FileInputStream(file);
// 파일을 업로드한다.
sftpChannel.put(fis, file.getName());
fis.close();
System.out.println("File uploaded successfully - "+ file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
disconnect();
}
파일을 다운로드 하는 부분입니다.
public void download(String fileName, String localDir) throws Exception{
byte[] buffer = new byte[1024];
BufferedInputStream bis;
connect();
try {
// Change to output directory
String cdDir = fileName.substring(0, fileName.lastIndexOf("/") + 1);
sftpChannel.cd(cdDir);
File file = new File(fileName);
bis = new BufferedInputStream(sftpChannel.get(file.getName()));
File newFile = new File(localDir + "/" + file.getName());
// Download file
OutputStream os = new FileOutputStream(newFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
int readCount;
while ((readCount = bis.read(buffer)) > 0) {
bos.write(buffer, 0, readCount);
}
bis.close();
bos.close();
System.out.println("File downloaded successfully - "+ file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
disconnect();
}
라이브러리를 이용하는 모듈을 위와 같이 공통모듈식으로 만들어 놓고나서
해당 모듈을 호출하는 부분은 아래와 같이 간단합니다.
저는 SFTP에 대한 정보를 ini파일에 두고서 해당 정보를 읽어와서 접속하는 부분으로 작업을 하였습니다.
public static void main(String[] args) {
Properties p = new Properties();
String localPath = "";
String remotePathUp = "";
String remotePathDown = "";
String host = "";
Integer port = 22;
String user = "";
String password ="";
try{
//ini 파일 읽기
p.load(new FileInputStream("C:\\~~~~~~~~.ini"));
//ftproot 경로 가져오기
host = p.getProperty("ftp_host");
port = Integer.parseInt(p.getProperty("ftp_port"));
user = p.getProperty("ftp_user");
password = p.getProperty("ftp_password");
localPath = p.getProperty("local_path");
remotePathUp = p.getProperty("remote_path_up");
remotePathDown = p.getProperty("remote_path_down");
PrepaidFTP ftp = new PrepaidFTP(host, port, user, password);
ftp.upload(localPath+"filetoupload.txt", remotePathUp);
ftp.download(remotePathUp+"filetodownload.txt", localPath);
} catch (Exception e)
{
System.out.println(e);
}
}
작은 도움이나마 되기를 바랍니다.
좋은 소스 감사감사
미천한 소스를 좋게 봐주셔서 감사합니다.
글 잘 봤습니다 . 풀봇하고 가요^^
감사합니다. 좋은하루 되세요~
먼가 예전 생각이 나네요. 예전가요를 들으면 그때 기억이 나듯이 그 코딩하던 시절이... ㅎㅎ
ㅎㅎㅎ 저도 간만에 해본것이라서 쉽지가 않습니다~ ㅋㅋ 잘 봐주셔서 감사합니다.