읽기

파일을 읽기 위해서는 다음 순서로 코드를 작성해야 합니다.

  1. 파일 객체 생성: - File file = new File("filename.txt");

  2. 파일 입력 스트림 생성: - FileInputStream inputStream = new FileInputStream(file);

  3. 버퍼 생성: - byte[] buffer = new byte[1024];

  4. 입력 스트림으로부터 데이터를 버퍼에 읽어옴: - inputStream.read(buffer);

  5. 버퍼에서 읽어온 데이터를 문자열로 변환: - String data = new String(buffer);

  6. 입력 스트림 닫기: -inputStream.close();

1. Byte 단위로 읽기

InputStream은 Byte 단위로 읽어 들이는 것으로 InputStream 확장해서 만든 FileInputStream 클래스를 사용하여 파일에서 데이터를 읽게 합니다.

예제 1 : Byte 단위로 읽기
FileInputStream fileInputStream = null;
try {
  fileInputStream =  new FileInputStream(fileName) ;
  int readChar = 0;
  while ((readChar = fileInputStream.read()) != -1) {
    System.out.println((char)readChar);
  }
} catch (IOException e) {
  System.out.println("파일을 확인해 주세요");
  throw new RuntimeException(e);
} finally {
  if (fileInputStream != null  ) {
    try {
      fileInputStream.close();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}
  • 3 line : 파일 객체 생성 합니다.

    • FileInputStream 생성자의 인수로 파일을 넘겨주면 내부에서 File를 객체를 생성합니다.

    • 파일 읽기의 1, 2번 사항 입니다.

  • 4 line : read() 메서드는 Data를 한 Byte씩 읽어서 값이 없으면 -1로 돌려 주는 메서드로 파일을 읽어 마지막 인지 체크하기 위해 선언한 변수로 초기값 0으로 설정합니다.

  • 5 line : Data를 한 Byte씩 읽어서 없으면 while문을 벗어납니다.

  • 6 line : 읽은 문자는 Char로 변환 해서 출력합니다.

  • 8 - 11 line : File에 관한 예외 처리 로직

  • 12 - 17 line : File을 열어서 작업을 했으므로 열려 있는 파일을 닫아야 합니다.

2-1-1. 예제 1의 문제점

한글 파일인 경우 한글이 깨지는 문제 입니다. 해당 문제를 해결하기 위해서는 문자셋을 지정해야 하므로 InputStreamReader 클래스를 사용하여 FileInputStream객체에서 읽어들인 데이터를 문자셋을 변환합니다.

  • 3 line : InputStreamReader 메서드 시그니처로의 두번째 파라메터에 문자셋을 지정 하여 읽어야 합니다.

    • 파일의 문자셋에 맞는 문자셋를 지정 합니다. ( "UTF-8", "EUC-KR" )

Byte 단위로 읽기 (문자셋 설정) - 전체 소스

2. Line 단위로 읽기

line 단위로 읽기 위해서는 reader 객체나 자바 8 이상에서는 Files 클래스를 이용하는 방법이 있습니다.

2-1. InputStream / Reader 클래스 사용

Reader 클래스를 상속 받은 BufferedReader를 Byte로 읽어 들이는 InputStream 클래스와 같이 사용해서 Line 단위로 읽게할 수 있습니다.

  • 3 - 6 line : Byte 단위로 읽어 들이는 FileInputStream 클래스에 InputStreamReader 클래스를 이용하여 문자셋으로 적용하고 읽어 들인 것을 BufferReader를 사용하여 Line단위로 읽을수 있게 합니다.

  • 7 - 9 line : bufferedReader.readLine()은 읽을 데이터가 없으면 null로 반환하고 있으면 라인의 데이터를 돌려 주는 메서드여서 readLine 변수를 사용하고 데이터가 없으면 while문을 탈출 합니다.

Line 단위로 읽기 - 전체 소스

3. Line 단위로 읽기 문자셋 변경

3-1. InputStream / Reader 클래스 사용

2-2. Line 단위로 읽기 코드에서 라인 단위로 읽은 데이터를 getBytes() 메서드를 사용해서 문자셋 변경을 하고 문자열로 바꾸면 됩니다.

  • 2 line : getBytes를 사용해서 문자셋 변환("UTF-8", "EUC-KR") 합니다.

  • 3 line : System.out으로 출력하기 위해 문자열로 변환합니다.

Line 단위로 읽기 문자셋 변경 - 전체 소스

3-2. FileReader / BufferedReader 클래스 사용

InputStream 클래스를 FileReader 클래스로 변경을 하면 됩니다. FileReader 샹성자로 두번째 파라메터가 Charset 타입을 전달 해야하며 내부적으로는 FileInputStream를 사용합니다. 다음은 FileReader 클래스생성자 입니다.

  • FileReader / BufferedReader 클래스 사용 소스

  • 3 - 4 line : InputStream 클래스 대신 FileReader 클래스로 변경하고 Charset.forName() 메서드를 사용하여 Charset 타입으로 변경합니다.

  • 나머지는 2-2-1과 동일 합니다.

Line 단위로 읽기 문자셋 변경 (FileReader / BufferedReader 클래스 사용) - 전체 소스

4. CSV 파일 읽기

CSV 파일은 쉼표(",")로 구분된 파일로 라인 단위로 읽고 쉼표(",") 하면 쉽게 만들수 있습니다.

CSV 파일을 관련 부분은 다음과 같습니다.

  • 6- 11 line : 해더 포함 이면 결과에 해더 정보를 추가하고 해더 미포함 이면 해더 포함으로 설정을 변경합니다. 그래야 14 line 에서 읽은 데이터를 6 line조건이 만족하여 결과에 데이터가 포함됩니다.

  • 19 - 28 line : 구분자가 있는 경우 구분자를 기준으로 21 line 에서 구분자로 잘라서 배열에 넣어서 반환 하고 구분자가 없는 경우 파라터로 받은 ( row ) 데이터를 그냥 반환 합니다.

    • 주의 사항 : 성능 및 트랜잭션애 대한 고려를 해야 합니다.

      • 업무처리를 여기서 하는 경우 : 성능, DB 처리 갯수는 여러 사항에 대해서 고려 하여 동기적, 비동기적으로 설계 할지 결정을 해아합니다.

      • 호출한 곳에서 하는 경우 : 성능, DB 처리 갯수등 여러 사항에 대해서 고려 해야 히지만 병렬, 분산 등을 선택의 폭이 넓을 것으로 생각이 됩니다. 업무처리를 여기서 하는 경우에서 병렬, 분산까지 고려 해서 코드를 작성하기는 난이도가 더 높습니다.

전체 소스는 다음과 같으며 소스에 대한 설명을 주석에 표시 하였습니다.

공통 유틸

4-1. 구분자 "," 인 EUC-KR로 된 파일을 UTF-8로 변환

공통 유틸을 사용의 read() 메서드 호출시 해더포함, 구분자(","), EUC-KR을 UTF-8로 변경 하기 위한 소스 코트 입니다.

헤더 포함
해더 미포함

Last updated