viper_9
40
2019-10-31 15:01:03 작성 2019-10-31 15:38:44 수정됨
2
229

java ) 최소 700만건 - 최대 2000만건 txt 파일을 읽을때 특정 index 중복값 제거하는 가장 효율적인 방법에 대해 질문드립니다.


안녕하세요 0년차 초보개발자입니다.


최소 700만건 - 최대 2000만건 txt 파일을 읽을때 

특정 index 중복값 제거하는 가장 효율적인 방법에 대해 질문드립니다.


해당 원본 txt파일구조는 

aaa|bbb|ccc|ddd| ......|zzz

111|222|333|444| ......|999

111|222|333|444| ......|999

111|222|333|444| ......|999

.

.

.

이런식으로 최소 700만줄에서 최대 2000만줄 정도의 파일이 여러개 있고

각 파일마다 특정 index 값만 빼서 비교하여 중복값은 제거 하고

새로운 파일로 만드는 로직을 만들고 싶습니다.


DB는 mySQL를 사용하고 있는데

필터링이 끝난 이후에 Insert를 해야하기 때문에

insert전에 필터링을 해줄수 있는 로직이 필요합니다.


while((line = br.readLine()) != null) {
writelist.add(line);
if(j >= 7000000) {
break;
}
j++;
}

int lastlength = 0;
while((line = br.readLine()) != null) {
String[] arr = line.split("\\|");
n = 0;
i = 0;
for (String test : writelist) {
i++;
arr2 = test.split("\\|");
lastlength = (arr2.length - 1);
System.out.println(" " + p + " ==== " + i);
if(Float.parseFloat(arr[lastlength]) == Float.parseFloat(arr2[lastlength])) {
n++;
}
}
if(n >= 2) {
isOverlap = true;
}
if(!isOverlap) {
bw.write(line + "\n");
k++;
}
if(p >= j) {
break;
}
p++;
}


위 코드는 방법구현에 대해 처음으로 짜본 코드인데

해당 코드로는 700만줄 while 한번 돌아 갈 때 

한줄 읽을 때 마다 그안에 for문으로 똑같은 700만줄 리스트를 돌리면서 비교하는 구문입니다.


해당 로직은 시간이 상당히 오래걸리다고 판단되어서 사용하지 못하였고,

두번째 방법으론


 try {
File file = new File(path);
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "euc-kr"));
List<HashMap<Object, Object>> list = new ArrayList<HashMap<Object,Object>>();
int j = 1;
String line = null;
while ((line = br.readLine()) != null) {
HashMap<Object, Object> inputData = new HashMap<Object, Object>();
String[] arr = line.split("\\|");


inputData.put("fff", arr[0]);
inputData.put("Rbbb", arr[1]);
inputData.put("fff", arr[2]);
inputData.put("ddd", arr[3]);
inputData.put("eee", arr[4]);
inputData.put("fff", arr[5]);
list.add(inputData);

if( j >= 7000000) {
break;
}
j++;
}
br.close();
List<HashMap<Object, Object>> result = distinctArray(list, "fff");
}catch(Exception e) {
e.printStackTrace();
}
}
public static List<HashMap<Object, Object>> distinctArray(List<HashMap<Object, Object>> target, Object key){
if(target != null){
target = target.stream().filter(distinctByKey(o-> o.get(key))).collect(Collectors.toList());
}
return target;
}
public static <T> Predicate<T> distinctByKey(Function<? super T,Object> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}


700만건 파일 읽어서 List<Map>에 담아서 키값 비교해서 제거하는 알고리즘?(해당 메소드는 검색으로 찾아왔습니다)


를 사용하려했으나 위보다 Map에 담을 데이터 훨씬많고 700만건을 List에 담으려니 memory관련 error가

떨어져서 쓸 수가 없었습니다.


가급적 DB를 안쓰고 이 작업을 수행하게끔 해주고싶은데

동종업계에 계신 선배님들의 경험이나 조언이 필요합니다.

해당 프로젝트는 spring 로 구성되어있습니다.


긴 글 읽어주셔서 감사합니다.

처음으로 올리는 질문이라 질문방식이 잘못 되었을 수도 있습니다.

이부분에 대해서 말씀해주시면 고쳐서 다시 질문 올리도록 하겠습니다.

0
0