티스토리 뷰


새로운 어플리케이션을 개발하면서 IO Package 를 사용하던 기존의 FileUtil 을 버리고 새로 만들기로 했습니다.
그 중 일부가 NIO Package를 사용한 파일 복사 메소드인데요. 원리를 알고 나면 크게 어려울 것은 없으며, 다만 ByteBuffer의 쓰임새에 대해서 100% 이해를 하고 있어야만 정확한 사용이 가능합니다.

실제 구현한 FileUtil 클래스에서 copy() 메소드를 발췌해봤습니다.

public void copy(Vector logList) throws IOException {
	//***** 파일 복사용으로 사용될 IO,NIO Package 객체 *****
	FileChannel inChannel = null;
	FileChannel outChannel = null;
	//******************************************************

	for(int idx=0; idx<logList.size(); idx++) {
		RandomAccessFile sourceFile = null;
		RandomAccessFile targetFile = null;
		try {
			sourceFile = new RandomAccessFile((String) logList.get(idx), "rw");
			targetFile = new RandomAccessFile(config.getWorkTempPath() + File.separator
					+ extractFileNameFromPath((String) logList.get(idx)), "rw");
			// 파일 입력 채널 생성 (원본으로 부터 읽어 들이기 위함)
			inChannel = sourceFile.getChannel();
			// 파일 출력 채널 생성 (복제 대상 파일에 쓰기 위함)
			outChannel = targetFile.getChannel();

			// 1024 크기의 입출력을 위한 ByteBuffer 생성
			ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
			// 버퍼를 비운다
			buffer.clear();

			// 입력의 끝에 도달 할 때 까지 반복한다.
			while (true) {
				if (inChannel.read(buffer) == -1) { // 더이상 입력이 없으면 Loop 종료
					break;
				}

				buffer.flip(); // 현재 위치가 버퍼의 한계가 되게 하고 버퍼의 위치를 처음으로 이동.
				outChannel.write(buffer); //출력 채널에 버퍼를 할당.
				buffer.clear(); //버퍼를 비우고 버퍼의 위치를 처음으로 이동
			}
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			inChannel.close();
			outChannel.close();

			sourceFile.close();
			targetFile.close();
		}
	}
}

주요 코드별로 주석을 달아놓았으므로 참조하면 도움이 될 것입니다.

[copy(Vector logList) 메소드의 기능]

1. 인자로 받은 logList 라는 Vector 에는 n개 파일들의 절대 경로가 세팅되어 있다.

2. logList Vector 에 있는 파일 경로 갯수만큼 파일을 복사하는 로직을 반복 수행하도록 되어 있다.

3. 반복문 안에서는 복사 원본이 되는 파일의 RandomAccessFile 인스턴스를 생성하고 input channel 을 받아온다.

4. 새로 생성될 파일 또한 RandomAccessFile 인스턴스를 생성하고 output channel 을 받아온다.

5. 1024 크기의 ByteBuffer 를 생성하되 allocateDirect() 를 통해 생성한다.

6. ByteBuffer는 이제부터 데이터를 담아 나를 그릇 역할을 하게 된다.

7. input channel 을 통해 원본 파일 내용을 Buffer 크기만큼 Buffer 에 담고

8. output channel 을 통해서는 신규 파일에 방금 Buffer 에 담긴 내용을 밀어넣는다.

9. 한번 쓰여진 Buffer 는 flip() 과 clear() 과정을 거쳐서 초기화한 후에 7, 8 과정을 반복한다.

10. 원본으로 부터 읽어들인 내용이 없을 경우 반복문을 빠져나가는데 여기까지가 파일 1개에 대한 처리이다.

11. 모든 파일에 대한 처리가 끝나면 finally 부분에서 close() 를 통해 모든 자원을 해제 한다.

♣ 인자값으로 반드시 Vector 형태의 파일 리스트일 필요는 없습니다.

'프로그래밍 > Java' 카테고리의 다른 글

java.io.FilenameFilter 의 기본 활용법  (0) 2010.02.02
Java로 UTF-8 파일 쓰기  (0) 2010.02.02
Apache Commons Project - XMLConfiguration TIP#1  (1) 2009.12.09
Apache Commons Project - Configuration  (2) 2009.12.09
ASCII Code Table  (0) 2009.10.16
공지사항