///////
Search
🛷

황준하

대용량 파일 처리 프로젝트

파일 읽어오기

320만개 이상의 데이터를 처리하다보니 소스코드안에서 선언과 초기화를 하기에는 너무 비효율적이다. 그래서 외부 csv파일을 불러와서 데이터를 받는 학습을 하였다.
public void readByLine(String filename){ try (BufferedReader br = Files.newBufferedReader(Paths.get(filename), StandardCharsets.UTF_8)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { throw new RuntimeException(e); } }
Java
복사
BufferedReader br = Files.newBufferedReader(Paths.get(filename), StandardCharsets.UTF_8
다음과 같은 방식이 최근 가장 주로 사용되는 파일 불러오는 방식이다.

데이터를 입력하면 List에 파싱해서 반환해주는 메소드

데이터를 저장할 도메인 구현

public class PopulationMoveReview { private int fromSido; private int toSido; public PopulationMoveReview(int fromSido, int toSido) { this.fromSido = fromSido; this.toSido = toSido; } public int getFromSido() { return fromSido; } public int getToSido() { return toSido; } }
Java
복사
전입 도시 코드와 전출 도시 코드를 저장할 두 개의 필드 변수와 생성자, getter를 생성했다.

Method를 설계하는 방법

Method는 단일 책임의 원칙을 적용 시켜서 만들어야 한다.
1.
논리적 설계 - 기능이 어떤 것인지 써본다.
2.
물리적 설계 - Java로 코딩하면 어떤 모양이 될 것인지 써보기
3.
구현 - 설계를 바탕으로 코딩
메소드 이름은 그 기능이 어떤 기능을 하는지 알 수 있도록 지어야 한다.

데이터를 파싱해주는 메소드 구현

1.
논리적 설계
public PopulationMoveReview parse(String data) { return new PopulationMoveReview(11, 11); }
Java
복사
다음과 같은 매개변수를 받아서 객체를 리턴해주는 메소드를 구현한다.
2.
구현
public PopulationMoveReview parse(String data) { String[] s = data.split(","); return new PopulationMoveReview(s[0], s[6]); }
Java
복사
다음과 같이 구현했다. String형 인자를 받을 수 있도록 PopulationMoveReview클래스 생성자를 오버로딩 하였다.
public PopulationMoveReview(int fromSido, int toSido) { this.fromSido = fromSido; this.toSido = toSido; } public PopulationMoveReview(String fromSido, String toSido) { this.fromSido = Integer.parseInt(fromSido); this.toSido = Integer.parseInt(toSido); }
Java
복사

두개의 메소드를 합쳐서 구현

public List<PopulationMoveReview> getListByData(String filename){ List<PopulationMoveReview> pml = new ArrayList<>(); try (BufferedReader br = Files.newBufferedReader(Paths.get(filename), StandardCharsets.UTF_8)) { String line; while ((line = br.readLine()) != null) { pml.add(parse(line)); } br.close(); } catch (IOException e) { throw new RuntimeException(e); } return pml; }
Java
복사

List에서 특정 콜론만 뽑아서 파일로 저장하기

파일 저장하는 메소드

public void createAFile(String filename) throws IOException { File file = new File(filename); file.createNewFile(); }
Java
복사

파일 내용 입력하는 메소드

public void write(List<String> strs, String filename) { File file = new File(filename); try { BufferedWriter writer= new BufferedWriter(new FileWriter(file)); for (String str : strs) { writer.write(str); } writer.close(); } catch (IOException e) { throw new RuntimeException(e); } }
Java
복사

도전과제: 도시 매핑

public Map<Integer, String> setSidoMap(){ Map<Integer, String> sidoMap = new HashMap<>(); sidoMap.put(11, "서울특별시"); sidoMap.put(26, "부산광역시"); sidoMap.put(27, "대구광역시"); sidoMap.put(28, "인천광역시"); sidoMap.put(29, "광주광역시"); sidoMap.put(30, "대전광역시"); sidoMap.put(31, "울산광역시"); sidoMap.put(41, "경기도"); sidoMap.put(42, "강원도"); sidoMap.put(43, "충청북도"); sidoMap.put(44, "충청남도"); sidoMap.put(45, "전라북도"); sidoMap.put(46, "전라남도"); sidoMap.put(47, "경상북도"); sidoMap.put(48, "경상남도"); sidoMap.put(50, "제주특별자치도"); return sidoMap; }
Java
복사
public Map<Integer, Integer> setSidoMapV2(){ Map<Integer, Integer> sidoMapV2 = new HashMap<>(); sidoMapV2.put(11, 1); sidoMapV2.put(26, 2); sidoMapV2.put(27, 3); sidoMapV2.put(28, 4); sidoMapV2.put(29, 5); sidoMapV2.put(30, 6); sidoMapV2.put(31, 7); sidoMapV2.put(41, 8); sidoMapV2.put(42, 9); sidoMapV2.put(43, 10); sidoMapV2.put(44, 11); sidoMapV2.put(45, 12); sidoMapV2.put(46, 13); sidoMapV2.put(47, 14); sidoMapV2.put(48, 15); sidoMapV2.put(50, 16); return sidoMapV2; }
Java
복사
각 도시 코드를 키로하여 value로 String이 들어있는 Map을 이용한다.
setSidoMapV2를 사용하면 1~16까지의 Int value가 매핑된다.

Map으로 어디로 많이 갔는지 개수 세기

알파벳 개수 세기 할 때 사용했던 로직을 응용하여 구현한다.
public Map<String, Integer> getMoveCnt(List<PopulationMove> pml) { Map<String, Integer> moveCntMap = new HashMap<>(); for (PopulationMove pm : pml) { String key = pm.getFromSido() + "," + pm.getToSido(); if(moveCntMap.get(key) == null){ moveCntMap.put(key, 1); } moveCntMap.put(key, moveCntMap.get(key) + 1); } return moveCntMap; }
Java
복사
해당하는 key에 value가 null이면 새로 초기화한다.
String targetFilename = "each_sido_cnt.txt"; ps.createAFile(targetFilename); List<String> cntResult = new ArrayList<>(); for (String key : map.keySet()) { String[] fromto = key.split(","); //매핑을 해서 저장 String s = String.format("[%s, %s, %d],", sidoMapV2.get(Integer.parseInt(fromto[0])), sidoMapV2.get(Integer.parseInt(fromto[1])), map.get(key)); // String s = String.format("key:%s value:%d\n", key, map.get(key));2 cntResult.add(s); } ps.write(cntResult, targetFilename);
Java
복사
[si, do, value]의 형태로 새로운 txt파일에 저장한다.