如何在java中将一个大的csv文件快速转换成json数组
我想将一个大的csv文件(如20000到50000个记录文件)转换为json数组,但转换需要将近1分钟,有没有办法在5秒内完成如何在java中将一个大的csv文件快速转换成json数组,java,json,Java,Json,我想将一个大的csv文件(如20000到50000个记录文件)转换为json数组,但转换需要将近1分钟,有没有办法在5秒内完成 ResourceBundle rb = ResourceBundle.getBundle("settings"); String path = rb.getString("fileandfolder.Path"); System.out.println(path + "ssdd"); String csvPath =
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);
试一试
使用+连接字符串速度较慢,应使用StringBuilfer或StringBuffer。此csv=csv+((char)res)
非常慢,一次读取一个字符,然后使用旧字符串和新字符分配新字符串
要将文件中的所有文本加载到字符串中,请执行以下操作:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
(请注意,如果使用java 7,有一种更干净的方法)
像这样使用,而不是循环:
String csv = readFile(orname, StandardCharsets.UTF_8);
您的代码中有两个明显的性能问题,这两个问题都在这个代码段中:
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时是否存在性能问题;i、 在这个片段中
JSONArray array = CDL.toJSONArray(csv);
String Csvs = array.toString();
不幸的是,我们不知道您实际使用的JSONArray
和CDL
类是什么。因此,很难说它们为什么慢,或者是否有更快的转换方法。(但我怀疑,最大的性能问题在前面的代码片段中。)Cvs库。。???你能给我看一下它的例子吗?我已经从代码中删除了它,不再需要它了。然后改变你的代码以反映这一点,你的代码不会按原样编译。所以longtime3=System.nanoTime()-start2代码>可能应该是longtime3=System.nanoTime()-start3代码>请注意,通过提供大量不必要的文件读取代码(显然没有计时),您已经把这里的很多人弄糊涂了。一个网络响应中的50k条目听起来是个坏主意。他没有计时读取数据,他只是计时字符串到数组的转换,这仍然没有帮助,他检查的时间是将String
放入JSONArray
@mikea的过程,在你也投票否决我之前,注意OP使用start2
来计时,而不是start3
@JonathanDrapeau不正确,long start3=System.nanoTime()
不用于时间计算。@JonathanDrapeau除非他删除了一行,否则我知道它位于每次读取文件一个字符的循环上方。检查正在计时的内容,这不是问题所在。根据另一个答案,他没有计时文件的这一部分code@mikea根据另一个答案,,他是从start2
开始计时的,而不是start3
@JonathanDrapeau,我查过了。他从start2
开始计时,而不是start3
。这是一个很好的猜测,就在复制的部分上方的一行。无论谁否决了这一点,认为“没有用”,猜猜在接受的答案,即循环中,什么代码最终会变慢。除非我们找到start2
的初始化位置,否则这可能不是问题。是的。。。计时代码也相当混乱。但是我准备接受OP的代码确实需要几分钟来处理一个大文件。性能问题是真实存在的。
JSONArray array = CDL.toJSONArray(csv);
String Csvs = array.toString();