대용량 파일 처리 프로젝트
파일 읽어오기
•
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파일에 저장한다.