Overview
최근 프로그램적으로 서버에서 서버로 접속하여 특정경로에 있는 파일을 읽거나, 지우는 기능을 개발해야 되는 상황이 발생하였다. 굳이라는 생각이 들지만 여러가지 상황에 의해 기능 개발을 하였고 그 과정에서 기록이 필요하여 남긴다. 보통 scp, ssh 등등 같이 linux, unix 상 터미널로도 접속, 파일전송을 할 수 있다. 또한 Java에서도 pure하게 Keyword를 수행할 수 있지만, 외부라이브러리(JSCH)를 통해 SFTP를 사용하였다.
Usage
#1 Java Runtime사용.
Runtime rt = Runtime.getRuntime();
Process process = rt.exec("rm /tmp/*");
#2 JSCH 사용
#2-1
implementation 'com.jcraft:jsch:0.1.55'
Build.gradle 에서 dependency 추가.
#2-2 리소스 관리 부분
private Session createSession(String username, String password, String host) throws JSchException {
JSch jsch = new JSch();
//1
Session session = jsch.getSession(username, host, SFTP_PORT);
session.setPassword(password);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
return session;
}
private ChannelSftp createSftpChannel(Session session) throws JSchException {
//2
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
return channelSftp;
}
//3
private void closeResources(Session session, ChannelSftp channelSftp, BufferedReader reader) {
try {
if (reader != null) reader.close();
if (channelSftp != null) channelSftp.disconnect();
if (session != null) session.disconnect();
} catch (IOException e) {
log.error("리소스 해제 중 오류 발생", e);
}
}
- 서버 username, password, host 정보를 정확히 기재한다.
- session.openChannel은 타입에 따라 알맞은 Instance를 반환하기 떄문에 필요에 맞는 키워드로 Instance를 사용한다.
- Resouce를 잘 관리해주자.(close)
#2-3 사용
public String readFileFromSftp(String username, String password, String host, String filePath, String fileName) {
Session session = null;
ChannelSftp channelSftp = null;
BufferedReader reader = null;
String xmlStr = "";
try {
session = createSession(username, password, host);
channelSftp = createSftpChannel(session);
if (channelSftp.isConnected()) {
log.info("SFTP 연결 성공");
xmlStr = readAndPrintFile(channelSftp, filePath, fileName);
} else {
log.error("SFTP 연결 실패");
}
return xmlStr;
} catch (Exception e) {
log.error("SFTP 작업 중 오류 발생", e);
} finally {
closeResources(session, channelSftp, reader);
}
return xmlStr;
}
private String readAndPrintFile(ChannelSftp channelSftp, String filePath, String fileName) throws Exception {
channelSftp.cd(filePath);
log.info("현재 디렉토리: {}", channelSftp.pwd());
log.info("디렉토리 내용: {}", channelSftp.ls(".").stream().toList());
log.info("디렉토리 내용: {}", channelSftp.ls(".").stream().collect(Collectors.toList()));
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(channelSftp.get(fileName + ".xml")))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
sb.append(line);
}
return sb.toString();
}
}
readAndPrintFile Method내 pwd, ls 등 linux Keyword function을 제공한다.
마치며,,,
보통 NAS나 볼륨이 공유된 상황이라 Files.readAllBytes 등의 Method를 사용하여 손쉽게 사용한다. 그리고 또는 AWS의 S3를 사용하기 때문에 위 기술된 SFTP까지 쓰는 케이스는 드물긴하다. 모든 내용은 상황과 여건에 맞게 사용해야된다. 또한 thorw로 처리했지만 try ~ catch blcok을 사용한 Exception처리를 하기 바란다.