java實現大批量json檔案資料去重
上週從資料採集部門拿到一批400份的json檔案,每個檔案裡30w+的json物件,物件裡有uid,對重複的uid,需要去重下.
本人電腦4核8G已經不能滿足了,總是記憶體不夠用.所以在伺服器上寫了一下(配置8核128G) ,結果讀取檔案以及去重都沒問題,
在最後的寫入是又是記憶體不夠了.所以總結了一下,整體的思路是,先把400份分為每份20份,這樣處理一下,就只有20份了,再把20份的json檔案處理去重整理成一份.
準備工作: 400份json檔案,每個檔名稱為1 (1).json..........1 (400).json
直接上程式碼
package com.ufc.user.controller;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class test2 {
public static void main(String[] args) {
//第一步400份json迴圈讀取,每次讀20份
for (int i = 21; i <= 401; i+=20) {
System.out.println(i);
test2 test1=new test2();
test1.testjson1(i);
}
//到此已經將400份json檔案處理成20份,而且這20份的每份中沒有重複的資料,但是不能保證第n份和第n1份兩者之間的資料有沒有重複,所以還需要將這20份合併成一份.
//第二步20份json檔名21.json,41json,61.json,81.json...401.json 一共20份,需要手動把20份的名稱改為1 (1).json...... 1 (20).json
//第三步將20份json檔案資料去重整理成一份
test2 test1=new test2();
for (int i = 1; i < 21; i++) {
System.out.println(i);
test1.testjson2(i);
}
//第四步匯出處理好資料的檔案,名稱為666.json
test1.str();
}
/**
* 讀取400分json檔案並將每20份json去重整理成1份
* @param rr
*/
public void testjson1(int rr) {
JSONArray arr = new JSONArray();
Set<String> testSet = new HashSet<String>();
int c=rr-20;
try {
for (int r = c; r < rr; r++) {
System.out.println("i=" + r);
String Path = "G:\\gjx_data\\json\\1 (" + r + ").json";
String str1 = new String(downFileByte(Path));
String[] str = str1.split("\n");
for (int i = 0; i < str.length; i++) {
Map maps = (Map) JSON.parse(str[i]);
String user_id = maps.get("user_id").toString();
testSet.add(user_id);
}
}
Iterator<String> it = testSet.iterator();
while (it.hasNext()) {
JSONObject obj = new JSONObject();
String str11 = it.next();
obj.put("uid", str11);
arr.add(obj);
}
String data = arr.toJSONString();
wirter1(data,rr);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 寫入檔案的方法
* @param s
* @param a
* @throws Exception
*/
public void wirter1(String s,int a) throws Exception {
FileWriter fw = null;
File f = new File("G:\\gjx_data\\json1\\"+a+".json");
try {
if (!f.exists()) {
f.createNewFile();
}
fw = new FileWriter(f);
BufferedWriter out = new BufferedWriter(fw);
out.write(s, 0, s.length() - 1);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("end");
}
Set<String> testSet1 = new HashSet<String>();
/**
* 將20份json資料去重整理成1份
* @param rr
*/
public void testjson2(int rr) {
try {
System.out.println("i=" + rr);
String Path = "G:\\gjx_data\\json1\\1 (" + rr + ").json";
String str1 = new String(downFileByte(Path));
JSONArray jsonarray=JSONArray.parseArray(str1+"]");//還是手動拼上好
for (int i = 0; i < jsonarray.size(); i++) {
JSONObject parse = JSONObject.parseObject( jsonarray.get(i).toString());
String uid = parse.getString("uid");
testSet1.add(uid);
}
} catch (Exception e) {
e.printStackTrace();
}
}
StringBuffer sb=new StringBuffer();
/**
* 處理成每行一個uid的字串
*/
public void str(){
Iterator<String> it = testSet1.iterator();
while (it.hasNext()) {
String str11 = it.next();
sb.append(str11);
sb.append("\n");
}
String data =sb.toString();
try {
wirter1(data,666);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 讀取檔案方法
* @param downLoadPath
* @return
* @throws Exception
*/
public static byte[] downFileByte(String downLoadPath) throws Exception {
byte[] return_arraybyte = null;
InputStream ins = new FileInputStream(downLoadPath);
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
byte[] buf = new byte[5 * 1024 * 1024];
int bufsize = 0;
while ((bufsize = ins.read(buf, 0, buf.length)) != -1) {
byteOut.write(buf, 0, bufsize);
}
return_arraybyte = byteOut.toByteArray();
byteOut.close();
ins.close();
return return_arraybyte;
}
}