我需要找出csv文件中每个字段的最大长度。
例如,在以下cvs
文件中,因为
1)var1
具有最长的字符串shj
,其为3个字符,
2)var2
包含最长的字符串asdf
- 4个字符
3)var3
有asddfs
- 6个字符
var1,var2,var3
a,asdf,df
aa,,
shj,,asddfs
所以,我需要的结果是数组int [] maxLength = {3,4,6}
到目前为止,我正在使用CSV Reader API。这是我的代码
CSVReader reader = new CSVReader (new FileReader(Looks.fileName));
int [] maxLength = new int[reader.readNext().length];
for (int i = 0; i < row.length; i++) {
maxLength[i] = row[i].trim().length() ;
}
while ((row = reader.readNext()) !=null ) {
for (int i = 0; i < row.length; i++) {
maxLength[i] = Math.max(maxLength[i] , row[i].trim().length() );
}
}
reader.close();
工作正常。但对于一个巨大的文件来说太慢了。我有大约100,000,000行。
有没有有效的方法呢?我能否以某种方式使用setAsciiStream
来更有效地估计长度?
答案 0 :(得分:2)
CSVReader
是否已缓冲?如果没有,请用FileReader
包裹BufferedReader
(并使其成为一个漂亮的大缓冲区大小)。
答案 1 :(得分:1)
你的代码尽可能高效 - 它只读取每个字节一次,并且不会对文件进行任何昂贵的搜索。
将FileReader
包裹在BufferedReader
中可能会提高效果 - 尽管CSVReader
内部使用BufferedReader
并非不可能。
从磁盘读取100,000,000行的速度存在物理限制。在决定你的CSV阅读器很慢之前,值得对你可以编写的最简单的程序进行基准测试,该程序读取整个文件,看看需要多长时间。
BufferedReader reader = new BufferedReader(new FileReader filename);
char[] buffer = new char[1024**1024*10]; // 10MB; whatever
while(reader.read(buffer,0,buffer.length) >= 0) {
// nothing
}
reader.close();
更新:假设您正在使用OpenCSV,我确认了我的怀疑。
以下是OpenCsv的来源:http://sourceforge.net/p/opencsv/code/HEAD/tree/trunk/src/au/com/bytecode/opencsv/
CSVReader
的构造函数将Reader
包裹在BufferedReader
中,如果它不是BufferedReader
。
CSVReader.readNext()
只是反复调用BufferedReader.readLine()
,并对字符进行一些非常基本的操作。
这是 读取文件的最快方式:从头开始,一直读到结束,使用缓冲区,以便底层磁盘读取的大小与硬件和设备相同司机更喜欢。
在一个大文件上运行上面的程序,你会发现它需要与你的CSV解析程序相同的时间 - 因为即使我没有做任何明显的处理,它也有同样的瓶颈。你的 - 从磁盘读取的速度。
确实cat largefile >/dev/null
(UNIX)或type largefile >NUL
需要相似的时间。
使用分析器运行您的代码,您会发现它花费更多的时间等待read()
(在本机方法中是核心Java的一部分)而不是其他任何地方。
您无法对Java程序执行任何操作来加快速度。您可以通过调整硬件和/或操作系统来加快速度 - 例如调整文件系统参数和驱动程序设置,将文件放在RAMdisk或SSD上,等等。