InputStream 클래스를 FileReader 클래스로 변경을 하면 됩니다. FileReader 샹성자로 두번째 파라메터가 Charset 타입을 전달 해야하며 내부적으로는 FileInputStream를 사용합니다. 다음은 FileReader 클래스생성자 입니다.
publicFileReader(String fileName,Charset charset) throws IOException { super(newFileInputStream(fileName), charset);}// super 로 Charset 을 전달 하기 위해서는 Charset.forName(fromCharset)을 사용해야 한다.publicInputStreamReader(InputStream in,Charset cs) { super(in);if (cs ==null)thrownewNullPointerException("charset"); sd =StreamDecoder.forInputStreamReader(in,this, cs);}
CSV 파일은 쉼표(",")로 구분된 파일로 라인 단위로 읽고 쉼표(",") 하면 쉽게 만들수 있습니다.
CSV 파일을 관련 부분은 다음과 같습니다.
// 라인 단위 읽기row =convertCharSet(br,frpVO.getToCharset());while (row !=null) {// CSV 헤더 포함 여부if (frpVO.isHeader()) {// 반환 값 List에 저장results.add(getCols( frpVO.getDelimiter(), row)); } else {frpVO.setHeader(true); }// 다음 라인 단위 읽기 row =convertCharSet(br,frpVO.getToCharset());}// CSV 파일과 같이 구분자가 있는 것에 대한 처리privatestatic<T>TgetCols(String delimiter,String row) {if (delimiter !=null) {String[] columns =row.split(delimiter);// TODO 이관에서 비동기 처리 저장 System.out.println("String[] :" + columns);return (T) columns; } else {// TODO 이관에서 비동기 처리 저장System.out.println("String :"+ row); }return (T) row;}
6- 11 line : 해더 포함 이면 결과에 해더 정보를 추가하고 해더 미포함 이면 해더 포함으로 설정을 변경합니다. 그래야 14 line 에서 읽은 데이터를 6 line조건이 만족하여 결과에 데이터가 포함됩니다.
19 - 28 line : 구분자가 있는 경우 구분자를 기준으로 21 line 에서 구분자로 잘라서 배열에 넣어서 반환 하고 구분자가 없는 경우 파라터로 받은 ( row ) 데이터를 그냥 반환 합니다.
주의 사항 : 성능 및 트랜잭션애 대한 고려를 해야 합니다.
업무처리를 여기서 하는 경우 : 성능, DB 처리 갯수는 여러 사항에 대해서 고려 하여 동기적, 비동기적으로 설계 할지 결정을 해아합니다.
호출한 곳에서 하는 경우 : 성능, DB 처리 갯수등 여러 사항에 대해서 고려 해야 히지만 병렬, 분산 등을 선택의 폭이 넓을 것으로 생각이 됩니다. 업무처리를 여기서 하는 경우에서 병렬, 분산까지 고려 해서 코드를 작성하기는 난이도가 더 높습니다.
전체 소스는 다음과 같으며 소스에 대한 설명을 주석에 표시 하였습니다.
공통 유틸
packagecom.hyomee;importjava.io.*;importjava.util.ArrayList;importjava.util.List;publicclassFileReadUTIL { /** * 파일을 읽고 List로 돌려줌 * @param file 파일 명이 포함된 파일 경로 * @param frpVO 파일을 읽고 해석 할 때 속성 * @return * @param <T> List안에 있는 객체로 String or String[] */publicstatic <T> List<T> read(String file,FileReadParameterVO frpVO ) {List<T> results =newArrayList<>();BufferedReader br =null;String row =null;try {// 문자셋 포함 여부에 따른 문자셋 변환if (frpVO.getCharset() !=null) { br =newBufferedReader(new InputStreamReader(new FileInputStream(file),frpVO.getCharset())); } else { br =newBufferedReader(new InputStreamReader(new FileInputStream(file))); }// 라인 단위 읽기 row =convertCharSet(br,frpVO.getToCharset());while (row !=null) {// CSV 헤더 포함 여부if (frpVO.isHeader()) {// 반환 값 List에 저장results.add(getCols( frpVO.getDelimiter(), row)); } else {frpVO.setHeader(true); }// 다음 라인 단위 읽기 row =convertCharSet(br,frpVO.getToCharset()); } } catch ( UnsupportedEncodingException e) {System.out.println("문자셋을 확인해 주세요.");thrownewRuntimeException(e); } catch (IOException e) {System.out.println("파일을 확인해 주세요.");thrownewRuntimeException(e); } finally {if (br !=null ) {try {br.close(); } catch (IOException e) {thrownewRuntimeException(e); } } }return results; } /** * CSV 파일과 같이 구분자가 있는 것에 대한 처리 * @param delimiter * @param row * @return * @param <T> */privatestatic <T> TgetCols(String delimiter,String row) {if (delimiter !=null) {String[] columns =row.split(delimiter);// TODO 이관에서 비동기 처리 저장 System.out.println("String[] :" + columns);return (T) columns; } else {// TODO 이관에서 비동기 처리 저장System.out.println("String :"+ row); }return (T) row; } /** * CSV 파일과 같이 구분자에 의해서 행/열로 되어 있는 데이터에 * 대해서 열을 String[]로 변환 후 반환 * - 문자셋 이 없으면 String 반환 * @param br * @param charset * @return * @throwsIOException */privatestaticStringconvertCharSet(BufferedReader br,String charset ) throwsIOException {String record =br.readLine();if ( charset !=null&& record !=null) {byte[] utf8Bytes =record.getBytes(charset);returnnewString(utf8Bytes, charset); }return record; }}classFileReadParameterVO {privateboolean isHeader; // CSV 해더 포함 여부privatefinalString delimiter; // CSV 열 구분자privatefinalString charset; // 원본 파일의 문자셋privatefinalString toCharset; // 변경할 문자셋FileReadParameterVO(boolean isHeader,String delimiter,String charset,String toCharset) {this.isHeader= isHeader;this.delimiter= delimiter;this.charset= charset;this.toCharset= toCharset; }// 해더 포함 기본 파라메터 생성publicstaticFileReadParameterVOinitFrpVO() {returnnewFileReadParameterVO(true,null,null,null) ; }// 해더 포함 문자셋 지정 생성publicstaticFileReadParameterVOinitFrpVO(String charset) {returnnewFileReadParameterVO(true,null, charset,null) ; }// 해더 포함 문자셋을 다른 문자셋으로 변경publicstaticFileReadParameterVOinitFrpVO(String charset,String toCharset) {returnnewFileReadParameterVO(true,null, charset, toCharset) ; }// 해더 포함 여부 설정 , CSV 파일 열 구분자 지정publicstaticFileReadParameterVOinitFrpVO(boolean isHeader,String delimiter) {returnnewFileReadParameterVO(isHeader, delimiter,null,null) ; }// 해더 포함 여부 설정 , 문자셋을 다른 문자셋으로 변경publicstaticFileReadParameterVOinitFrpVO(boolean isHeader,String charset,String toCharset) {returnnewFileReadParameterVO(isHeader,null, charset, toCharset) ; }// 해더 포함 여부 설정 , CSV 구분자, 문자셋을 다른 문자셋으로 변경publicstaticFileReadParameterVOinitFrpVO(boolean isHeader,String delimiter,String charset,String toCharset) {returnnewFileReadParameterVO(isHeader, delimiter, charset, toCharset) ; }publicbooleanisHeader() {return isHeader; }publicbooleansetHeader(boolean isHeader) {returnthis.isHeader= isHeader; }publicStringgetDelimiter() {return delimiter; }publicStringgetCharset() {return charset; }publicStringgetToCharset() {return toCharset; }}
4-1. 구분자 "," 인 EUC-KR로 된 파일을 UTF-8로 변환
공통 유틸을 사용의 read() 메서드 호출시 해더포함, 구분자(","), EUC-KR을 UTF-8로 변경 하기 위한 소스 코트 입니다.