[英]How to convert a big csv file into json array quickly in java
我想將像20000到50000記錄文件這樣的大csv文件轉換為json數組,但是要轉換將近1分鍾,有沒有辦法在不到5秒的時間內實現它。
ResourceBundle rb = ResourceBundle.getBundle("settings");
String path = rb.getString("fileandfolder.Path");
System.out.println(path + "ssdd");
String csvPath = request.getParameter("DP") != null ? request
.getParameter("DP").toString() : "";
String orname = path + csvPath;
File file = new File(orname);
FileReader fin = new FileReader(file); //Read file one by one
BufferedReader bi = new BufferedReader(fin);
int res;
String csv = "";
while ((res = fin.read()) != -1) {
csv = csv + ((char) res); //Converted int to char and stored in csv
}
long start3 = System.nanoTime();
JSONArray array = CDL.toJSONArray(csv);
String Csvs = array.toString();
long time3 = System.nanoTime() - start3;
System.out
.printf("Took %.3f seconds to convert to a %d MB file, rate: %.1f MB/s%n",
time3 / 1e9, file.length() >> 20, file.length()
* 1000.0 / time3);
嘗試
StringBuilder sb = new StringBuilder();
while ((res = fin.read()) != -1) {
sb.append((char) res); //Converted int to char and stored in csv
}
String csv = sb.toString();
使用+連接字符串很慢,應該使用StringBuilfer或StringBuffer
您的代碼中存在兩個明顯的性能問題,在此代碼段中都存在:
while ((res = fin.read()) != -1) {
csv = csv + ((char) res);
}
第一個問題: fin
是一個無緩沖的FileReader
,因此每個read()
調用實際上都是在進行系統調用。 每個系統調用都是數百甚至數千條指令。 您正在為輸入文件中的每個字符執行此操作。
補救措施:從bi
而不是fin
讀取。 (大概就是您為之創建的。)
第二個問題:每次執行csv = csv + ((char) res);
您正在創建一個新字符串,該字符串比上一個字符長一個字符。 如果輸入文件中包含N
字符,則最終將復制大約N^2
字符以構建字符串。
補救措施:代替串聯字符串,使用StringBuilder ...像這樣:
StringBuilder sb = new StringBuilder();
....
sb.append((char) res);
....
String csv = sb.toString();
至此,尚不清楚將csv
字符串轉換為JSON時是否還有性能問題。 即在此片段中。
JSONArray array = CDL.toJSONArray(csv);
String Csvs = array.toString();
不幸的是,我們不知道您實際使用的是什么JSONArray
和CDL
類。 因此,很難說出它們為什么很慢,或者是否有更快的轉換方法。 (但是我懷疑最大的性能問題出在前面的代碼段中。)
這個csv = csv + ((char) res)
非常慢,您一次讀取一個char,然后分配一個包含舊字符串和新char的新字符串。
要將文件中的所有文本加載到字符串中,請執行以下操作:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
(來自https://stackoverflow.com/a/326440/360211 ,請注意,如果使用的是Java 7,則有一種更簡潔的方法)
像這樣使用而不是循環:
String csv = readFile(orname, StandardCharsets.UTF_8);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.