자바 인터페이스 쓰기





데이터 쓰기


FileSystem 클래스는 파일을 생성하기 위한 메서드들을 제공한다. 가장 간단한 메소드는 생성할 파일을 Path 객체로 받아서 출력 스트림으로 쓰는 것이다.


콜백 인터페이스를 넘겨주는 progressable과 같은 오버로드 메소드도 있어서 어플리케이션은 데이터노드의 쓰기 진행 상황을 계속 파악할 수 있다.


package org.apache.hadoop.util;

public interface Progressable {
    public void progress();
}


새로운 파일을 만드는 대신 append() 메소드로 기존 파일에 데이터를 추가할 수 도 있다.


public FSDataOutputStream append(Path f) throws IOExeption;


파일 추가 연산은 기존 파일을 열고 파일의 마지막 오프셋에 데이터를 쓸 수 있는 단일 쓰기를 허용한다. 어플리케이션이 이러한 API를 이용하면 파일을 닫은 후에도 기존 파일에 쓸 수 있으므로 로그파일과 같은 무제한 파일을 생성할 수 있다. 추가 연산은 선택사항이며 모든 하둡 파일 시스템에 구현된 것은 아니다. 예를 들어 HDFS는 가능하지만 S3 파일시스템은 파일 추가 연산을 지원하지 않는다.

오프셋 : 컴퓨터 과학에서 배열이나 자료 구조 오브젝트 내의 오프셋(offset)은 일반적으로 동일 오브젝트 안에서 오브젝트 처음부터 주어진 요소나 지점까지의 변위차를 나타내는 정수형이다. 이를테면, 문자 A의 배열이 abcdef를 포함한다면 ‘c’ 문자는 A 시작점에서 2의 오프셋을 지닌다고 할 수 있다. 어셈블리어와 같은 저급 프로그래밍 언어에서 오프셋은 상대 주소(relative address)로 부른다.


로컬 파일을 하둡 파일시스템에 복사하는 것은 64KB의 데이터 패킷이 데이터노드 파이프라인에 쓰일 때마다 하둡에 의해 progress() API에 특별한 행동을 보고하도록 지정할 수는 없으며(하둡 최신 버전의 변경 내역에서 다룬다.) 단순히 ‘뭔가 발생했다’ 는 것만 추측할 수 있다.


// 로컬 파일을 하둡 파일시스템으로 복사하기
public class FileCopyWithProgress {
    public static void main(String[] args) throws Exception {
        String localSrc = args[0];
        String dst = ars[1];

        InputStream in = new BufferedInputStream(new FileInputStream(localSrc));

        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(URI.create(dst), conf);
        OutputStream out = fs.create(new Path(dst), new Progressable() {
            public void progress() {
                System.out.print(".");
            }
        });

        IOUtils.copyBytes(in, out, 4096, true);
    }
}

...
hadoop FileCopyWithProgress input/docs/1400-8.txt hdfs://localhost/user/tom/1400-8.txt


현재 다른 하둡 파일시스템은 쓰는 동안 progress()를 호출하지 않는다.


FSDataOutputStream

FileSystem 클래스의 create() 메소드는 FSDataOutputStream을 반환하는데, FSDataInputStream과 같이 파일에서 현재 위치를 얻기 위한 메소드를 지원한다.


package org.apache.hadoop.fs;

public class FSDataOutputStream extends DataOutputStream implements Syncable {
    public long getPos() throws IOException {
        ...
    }
}


하지만 FSDataInputStream과 달리 FSDataOutputStream 은 파일 탐색(seek 기능)을 지원하지 않는다. HDFS는 열려 잇는 파일에는 순차쓰기를, 기존 파일에는 추가 연산만 지원하기 때문이다. 파일의 끝 외의 다른 부분에 쓰는 것은 지원하지 않으므로 쓰는 중에 탐색은 불가능하다.