본문 바로가기

기타

Commons Net의 FTPClient 사용하기

I. Commons net

Jakarta Commons의 net은 network utility collection입니다.
인터넷 프로토콜을 대부분지원하는 강력한 유틸리티로 사용이 쉽고 간결합니다.

클라이언트측의 기본적인 Internet protocol을 구현함으로서 고차원적인 abstract가 아닌

기본적인 프로토콜 access가 목적이기 때문에 부분적으로 object-orient 규칙에 위배되는

사항이 있다는것을 참고적으로 알자.

Commons net이 지원하는 프로토콜은 다음과 같다.

FTP
NNTP
SMTP
POP3
Telnet
TFTP
Finger
Whois
rexec/rcmd/rlogin
Time (rdate) and Daytime
Echo
Discard
NTP/SNTP


FTP의 경우 이전에는 Sun 패키지의 FtpClient를 사용했지만 이제는
Commons net의 FTP를 사용해 봅시다.

II. 준비물

Commons net은 자체적으로 ORO를 사용합니다.

Jakarta ORO란 파일이름의 치환, 분할, 필터링 등을 수행하기 위한 Perl5 호환 정규식, AWK와 같은 정규식, glob 표현, 그리고 유틸리티 클래스들을 제공하는 텍스트 처리 자바 클래스들입니다.

Commons net http://jakarta.apache.org/site/downloads/downloads_commons-net.cgi
Jakarta ORO http://jakarta.apache.org/site/downloads/downloads_oro.cgi

참고자료
Commons net API http://jakarta.apache.org/commons/net/apidocs/index.html
Commons net http://jakarta.apache.org/commons/net/

III. org.apache.commons.net.ftp 의 흐름

Sun 패키지의 FTPClient처럼 FTP여러 동작을 Commons net의 FTPClient로 구현해 보자.

다음 ① ~ ⑦까지 목록은 필수항목으로 구현되어야 합니다.

논리적으로 보면 간단합니다.


① FTPClient 생성
먼저 가장 중심적인 역할을 하는 FTPClient를 생성합니다.
FTPClient ftpClient = new FTPClient();

② FTPServer에 Connect
서버에 연결을 합니다.
ftpClient.connect(server);

③ 응답이 정상적인지 확인 합니다.
응답을 받아와서
int reply = ftpClient.getReplyCode();

정상적인지 확인해 봅니다.
if (!FTPReply.isPositiveCompletion(reply)) {
정상적이지 않으면 연결을 끊고 종료 합니다.
ftpClient.disconnect();
System.out.println("FTP server refused connection.");
} else {
정상적이면 계속 진행 합니다
System.out.println("Connect successful");
...
}

④ FTP Server 로그인
ftpClient.login(username, password);

⑤ 여러가지 작업을 합니다
list, get, put...

⑥ FTP Server 로그아웃
ftpClient.logout();

⑦ FTP Server disconnect
ftpClient.disconnect();


IV. 사용예제 - 목록보기
본격적으로 FTP에 접속하여 목록을 가져오는 소스를 봅시다.
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient.setControlEncoding("euc-kr"); // 한글파일명 때문에 디폴트 인코딩을 euc-kr로 합니다
ftpClient.connect("user.chollian.net"); // 천리안 FTP에 접속합니다

int reply = ftpClient.getReplyCode(); // 응답코드가 비정상이면 종료합니다
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
System.out.println("FTP server refused connection.");
} else {
System.out.print(ftpClient.getReplyString()); // 응답 메세지를 찍어봅시다


ftpClient.setSoTimeout(10000); // 현재 커넥션 timeout을 millisecond 값으로 입력합니다
ftpClient.login(username, password); // 로그인 유저명과 비밀번호를 입력 합니다

// 목록보기 구현

FTPFile[] ftpfiles = ftpClient.listFiles("/public"); // public 폴더의 모든 파일을 list 합니다
if (ftpfiles != null) {
for (int i = 0; i < ftpfiles.length; i++) {
FTPFile file = ftpfiles[i];
System.out.println(file.toString()); // file.getName(), file.getSize() 등등..
}
}

ftpClient.logout();
}

} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
} finally {
if (ftpClient != null && ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}


목록보기 방법에는 한가지 방법이 더 있습니다.

위의 코드는 해당 디렉토리내의 모든 파일을 가져오는 방법이며

다음 방법은 해당 디렉토리의 모든 파일을 정해진 수로 짤라 가져오는 방법이 있습니다.

위의 빨간색 코드대신 다음 코드가 들어갈 수 있습니다.


int page = 1;
FTPListParseEngine engine = ftpClient.initiateListParsing("/public"); // 목록을 나타낼 디렉토리
while (engine.hasNext()) {
FTPFile[] ftpfiles = engine.getNext(10); // 10개 단위로 끊어서 가져온다


System.out.println("------------------------ "+page+" ------------------------");

if (ftpfiles != null) {
for (int i = 0; i < ftpfiles.length; i++) {
FTPFile file = ftpfiles[i];
System.out.println(file.toString());
}
}
System.out.println("------------------------ "+(page++)+" -------------------------");
}

V. 사용예제 - get (파일 다운로드)

서버의 /public/테스트.txt 파일을 클라이언트의 C:\\Test\\테스트.txt 에 다운받는 예제.

File get_file = new File("C:\\Test\\테스트.txt");
OutputStream outputStream = new FileOutputStream(get_file);
boolean result = ftpClient.retrieveFile("/public/테스트.txt", outputStream);

outputStream.close();

VI. 사용예제 - put(파일 업로드)

클라이언트의 C:\\Test\\보내자.txt 파일을 서버의 /public/보내자.txt 에 업로드하는 예제.
만일 서버에 이미 /public/보내자.txt 파일이 있다면 덮어쓰게 된다.
File put_file = new File("C:\\Test\\보내자.txt");
inputStream = new FileInputStream(put_file);
boolean result = ftpClient.storeFile("/public/보내자.txt", inputStream);
inputStream.close();

VII. 사용예제 - append (파일업로드)
위의 예제와 같은 기능을 하지만 이미 파일에 동일한 파일이 있으면 false를 반환하면서 실행하지 않는다
File append_file = new File("C:\\Test\\더해라.txt");
inputStream = new FileInputStream(append_file);
boolean result = ftpClient.appendFile("/public/더해라.txt", inputStream);
inputStream.close();

VIII. 사용예제 - rename (파일 이름변경)

변경전 파일명과 변경할 파일명을 파라미터로 준다.
boolean result = ftpClient.rename("/public/바꾸기전파일.txt", "/public/바꾼후파일.txt");

IX. 사용예제 - delete (파일삭제)

삭제할 파일을 선택한다 .
boolean result = ftpClient.deleteFile("/public/test.txt");

X. 사용예제 - directory 생성

/public 에 oops 디렉토리를 생성한다.
boolean result = ftpClient.makeDirectory("/public/oops");

XI. 사용예제 - OS 커맨드 입력하기

/public 에 oops 디렉토리를 생성한다
ftpClient.sendCommand(FTPCommand.MAKE_DIRECTORY, "/public/oops");
sendCommand 함수에 FTPCommand의 실행할 OS명령을 static 멤버변수를 넘겨준다

XII. 사용예제 - 작업디렉토리 설정하기

작업디렉토리를 /public 설정한 후 oops 디렉토리를 설정한다 (위의 예제와 비교해보라!)
ftpClient.changeWorkingDirectory("/public");
boolean result = ftpClient.makeDirectory("oops"); // /public/oops 절대경로를 적지 않아도 된다


XIII. 사용예제 - 파일 및 전송형태 설정

파일 형태 설정
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);


파일 타입

FTP.BINARY_FILE_TYPE, FTP.ASCII_FILE_TYPE, FTP.EBCDIC_FILE_TYPE,
FTP.IMAGE_FILE_TYPE , FTP.LOCAL_FILE_TYPE

이 값을 설정하지 않으면 디폴트는 ASCII 이다.


전송 형태 설정
ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);


전송 타입
FTP.BLOCK_TRANSFER_MODE, FTP.COMPRESSED_TRANSFER_MODE

이값을 설정하지 않으면 디폴트는 FTP.STREAM_TRANSFER_MODE 이다.

 

출처 : http://www.jakartaproject.com/article/jakarta/1113911351166