CSV (comma-separated values)는 ,(콤마)로 구분되 있는 데이터파일
엑셀로 열어볼 수는 있으나 정보를 엑셀로 막 수정하다가는 파일 전체가 깨질수도 있으니
엑셀로는 읽기만 하는걸 권장
보통 DB에서 csv로 추출한 정보를 가공할때 쓰거나, 데이터를 분석할때등 많이 쓰임
[예시 데이터] (출처: data.go.kr)
CSV파일을 자바 프로젝트로 끌어온 뒤
데이터가 콤마(,)로 구분되있고 " 로 묶여있는걸 확인
엑셀이 아닌 메모장이나 notepad++ 등등으로 열어 읽어보는걸 추천
대부분 한글 문서는 UTF-8로 되있지만 아닐 수도 있으니 포맷을 확인해주자
파일을 읽어올때는 가장 빠른 StringBuilder를 사용
{CSVParser.java]
package ex03.csv;
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
// csv를 파싱하여 List<LineInfo>로 생성하는 파서
public class CSVParser {
// path : 파일경로,
// charset : 문자열 인코딩
public static List<LineInfo> makeCSVList(String path, String charset) {
List<LineInfo> list = new ArrayList<>();
try (FileReader fr = new FileReader(path, Charset.forName(charset));
BufferedReader br = new BufferedReader(fr); ) {
String headerStr = br.readLine();
List<String> headerList = csvLineToList(headerStr);
String str = null;
while((str = br.readLine()) != null) {
List<String> infoList = csvLineToList(str);
if(infoList == null) {
continue;
}
LineInfo info = new LineInfo(headerList, infoList);
list.add(info);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
// headerStr : 메뉴ID,식당ID,메뉴명,메뉴가격,메뉴태그정보,등록일시
// line : 1,858991,짜장면,6000,"주재료 : 돼지고기,야채,면,밀가루 / 조리법 : 볶음 / 소스 : 춘장",2020-10-26 16:45
private static List<String> csvLineToList(String csvLine) {
try {
String delemeter = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)";
List<String> list = new ArrayList<>();
String[] array = csvLine.split(delemeter);
for(String str : array) {
if(str.contains("메뉴ID")) {
str = str.substring(1,str.length());
}
str = str.replace("\"", "").strip();
list.add(str);
}
return list;
} catch (Exception e) {
System.err.println("csvLine : " + csvLine);
e.printStackTrace();
}
return null;
}
}
[LineInfo.java] 파일 읽기
package ex03.csv;
import java.util.List;
public class LineInfo {
private List<String> header; // 컬럼값
private List<String> info; // 데이터값
public List<String> getHeader() {
return header;
}
public void setHeader(List<String> header) {
this.header = header;
}
public List<String> getInfo() {
return info;
}
public void setInfo(List<String> info) {
this.info = info;
}
public LineInfo() {
super();
}
public LineInfo(List<String> header, List<String> info) {
super();
this.header = header;
this.info = info;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(); // 자추 출력할 예정, 성능 생각해서 StringBuilder로 만들기 StringBuffer도 되긴하는데 빌더가 좀더 빠르다
for(int i=0; i< header.size(); i++) {
sb.append(header.get(i) + ":" + info.get(i) + ", ");
}
return sb.toString();
}
public String getData(String header) {
int index = header.indexOf(header);
if(index != -1) {
return info.get(index);
} else {
return null;
}
}
public int getSize() {
return header.size();
}
}
[RunMain.java]
package ex03.csv;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// 전라남도 메뉴정보
// https://www.data.go.kr/data/15076624/fileData.do
// 전라남도 식당 정보
// https://www.data.go.kr/data/15076621/fileData.do
// 1. 식당과 모든 메뉴를 탐색할수 있는 기능
// 2. 식당을 찾으면 메뉴까지 보여주는 기능
// 3. 메뉴의 키워드를 조회하면 식당 정보가 같이 나올수 있는 기능
public class RunMain {
public static void main(String[] args) {
List<LineInfo> menuList = CSVParser.makeCSVList("전라남도_메뉴정보_20210120.csv", "UTF-8");
System.out.println("메뉴정보 출력");
// menuList.forEach((v) -> System.out.println(v));
System.out.println("--------------------------------------------");
List<LineInfo> restaurantList = CSVParser.makeCSVList("전라남도_식당정보_20201229.csv", "EUC-KR");
System.out.println("식당 정보 출력");
// restaurantList.forEach((v) -> System.out.println(v));
System.out.println("--------------------------------------------");
System.out.println("menuList size : " + menuList.size());
System.out.println("restaurantList size : " + restaurantList.size());
// 1. 식당과 모든 메뉴를 탐색할수 있는 기능
// 1.1 ) 무지성 접근 -> 결론 느리다!
// for(LineInfo info : restaurantList) {
// String rId = info.getData("식당ID");
// for(LineInfo minfo : menuList) {
// if(minfo.getData("식당ID").equals(rId)) {
// System.out.println(minfo);
// }
// }
// System.out.println("------------------------------------------------------");
//// System.out.println(rId);
// }
// 1.2 빠른 접근 방법
// -> map으로 자료구조 구성 필요!
// 식당ID - 식당 Line 정보
Map<String, LineInfo> restaurantIDToLineInfoMap
= new HashMap<String, LineInfo>();
// 식당ID - 메뉴 리스트
Map<String, List<LineInfo>> restaurantIDToMenuListMap
= new HashMap<String, List<LineInfo>>();
// 초기화 코드!
// 순서 존재, 식당-식당 List를 먼저 구성하고 메뉴 리스트를 구성해야함
for(LineInfo info : restaurantList) {
restaurantIDToLineInfoMap.put(info.getData("식당ID"), info);
}
for(LineInfo info : menuList) {
String rId = info.getData("식당ID");
List<LineInfo> list = restaurantIDToMenuListMap.get(rId);
if(list == null) {
list = new ArrayList<>();
restaurantIDToMenuListMap.put(rId, list);
}
list.add(info);
}
// restaurantIDToLineInfoMap.forEach((k,v) -> System.out.println(k+" : "+v));
// restaurantIDToMenuListMap.forEach((k,v) -> System.out.println(k+" : "+v));
// 출력부
for(LineInfo info : restaurantList) {
String rid = info.getData("식당ID");
System.out.println(info);
List<LineInfo> list = restaurantIDToMenuListMap.get(rid);
for(LineInfo info2 : list) {
System.out.println(info2);
}
System.out.println("-------------------------------------------");
}
System.out.println("------------------------------------------------------------");
// 2. 식당을 찾으면 메뉴까지 보여주는 기능
String keyword = "오리";
for(LineInfo info : restaurantList) {
if(info.getData("식당명").contains(keyword)) {
System.out.println("==========================================================");
System.out.println(info);
String rid = info.getData("식당ID");
List<LineInfo> list = restaurantIDToMenuListMap.get(rid);
for(LineInfo info2 : list) {
System.out.println(info2);
}
System.out.println("==========================================================");
}
}
System.out.println("------------------------------------------------------------");
// 3. 메뉴의 키워드를 조회하면 식당 정보가 같이 나올수 있는 기능
String keyword2 = "닭갈비";
for(LineInfo info : menuList) {
if(info.getData("메뉴명").contains(keyword2)) {
System.out.println("*********************************************************");
System.out.println(info);
String rid = info.getData("식당ID");
LineInfo info2 = restaurantIDToLineInfoMap.get(rid);
System.out.println(info2);
System.out.println("*********************************************************");
}
}
}
}
'자바' 카테고리의 다른 글
[Java] JSON Parsing (0) | 2023.12.19 |
---|---|
[Java] 예외처리 (Exception) (0) | 2023.12.19 |
제네릭 (0) | 2023.12.19 |
[Java] JDBC MVC (0) | 2023.11.30 |
[Java] JDBC (Java DataBase Connectivity) (0) | 2023.11.29 |