我正在编写一个应用程序,需要加载一个大型 csv 文件,该文件是纯数据且不包含任何标题。
我正在使用 fastCSV 库来解析文件,但是需要存储数据并需要检索特定字段。由于不需要整个数据,因此我将跳过每三行。 有没有办法在解析文件后设置 header 并将其保存在 ArrayList 等数据结构中?
这是加载文件的函数:
public void fastCsv(String filePath) {
File file = new File(filePath);
CsvReader csvReader = new CsvReader();
int linecounter = 1;
try (CsvParser csvParser = csvReader.parse(file, StandardCharsets.UTF_8)) {
CsvRow row;
while ((row = csvParser.nextRow()) != null) {
if ((linecounter % 3) > 0 ) {
// System.out.println("Read line: " + row);
//System.out.println("First column of line: " + row.getField(0));
System.out.println(row);
}
linecounter ++;
}
System.out.println("Execution Time in ms: " + elapsedTime);
csvParser.close();
} catch (IOException e) {
e.printStackTrace();
}
}
任何见解将不胜感激。
最佳答案
univocity-parsers支持字段选择并且可以非常轻松地做到这一点。它也比您正在使用的库更快。
以下是如何使用它来选择感兴趣的列:
输入
String input = "X, X2, Symbol, Date, Open, High, Low, Close, Volume\n" +
" 5, 9, AAPL, 01-Jan-2015, 110.38, 110.38, 110.38, 110.38, 0\n" +
" 2710, 289, AAPL, 01-Jan-2015, 110.38, 110.38, 110.38, 110.38, 0\n" +
" 5415, 6500, AAPL, 02-Jan-2015, 111.39, 111.44, 107.35, 109.33, 53204600";
配置
CsvParserSettings settings = new CsvParserSettings(); //many options here, check the tutorial
settings.setHeaderExtractionEnabled(true); //tells the parser to use the first row as the header row
settings.selectFields("X", "X2"); //selects the fields
解析并打印结果
CsvParser parser = new CsvParser(settings);
for(String[] row : parser.iterate(new StringReader(input))){
System.out.println(Arrays.toString(row));
}
}
输出
[5, 9]
[2710, 289]
[5415, 6500]
在字段选择上,您可以使用任何字段序列,并且具有不同列大小的行,解析器将很好地处理这个问题。无需编写复杂的逻辑来处理该问题。
在代码中处理文件
,更改上面的示例来执行此操作:
for(String[] row : parser.iterate(new File(filePath))){
... //your logic goes here.
}
如果您想要更可用的记录(带有键入的值),请改用此:
for(Record record : parser.iterateRecords(new File(filePath))){
... //your logic goes here.
}
加速
处理文件的最快方法是通过RowProcessor
。这是一个接收从输入解析的行的回调:
settings.setProcessor(new AbstractRowProcessor() {
@Override
public void rowProcessed(String[] row, ParsingContext context) {
System.out.println(Arrays.toString(row));
context.skipLines(3); //use the context object to control the parser
}
});
CsvParser parser = new CsvParser(settings);
//`parse` doesn't return anything. Rows go to the `rowProcessed` method.
parser.parse(new StringReader(input));
您应该能够快速解析非常大的文件。如果速度变慢,请查看代码(避免向内存中的列表或集合添加值,或者至少将集合预先分配到合适的大小,并使用 Xms 和 Xmx 标志为 JVM 提供大量内存来使用)。
现在这个解析器是您能找到的最快的。我做了这个performance comparison前段时间你可以引用一下。
希望这有帮助
披露:我是这个库的作者。它是开源且免费的(Apache V2.0 许可证)
关于java - 如何在java中保存从不带标题的csv文件中检索的特定数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54733879/