Java中如何高效读写CSV文件并将数据处理为数组?
Java高效处理CSV读写并转换为数组的方案
在Java中处理CSV,优先使用成熟的第三方库,自己手写解析逻辑容易踩转义字符、引号包裹字段的坑,还很难兼顾性能。下面是两个最常用的库的实现示例,以及性能优化要点:
一、OpenCSV(轻量易用)
OpenCSV是最流行的CSV处理库之一,API简洁,对CSV规范的支持很到位,适合中小规模文件处理。
1. 读取CSV并转换为二维数组
import com.opencsv.CSVReader; import com.opencsv.CSVReaderBuilder; import java.io.BufferedReader; import java.io.FileReader; import java.util.List; public class CsvToArrayExample { public static void main(String[] args) { // 用try-with-resources自动关闭流,避免资源泄漏 try (BufferedReader br = new BufferedReader(new FileReader("data.csv")); CSVReader reader = new CSVReaderBuilder(br) .withSkipLines(1) // 跳过表头行 .build()) { // 一次性读取所有行到List,再转二维数组 List<String[]> rowList = reader.readAll(); String[][] csvArray = rowList.toArray(new String[0][]); // 打印验证 for (String[] row : csvArray) { for (String cell : row) { System.out.print(cell + "\t"); } System.out.println(); } } catch (Exception e) { e.printStackTrace(); } } }
2. 将二维数组写入CSV
import com.opencsv.CSVWriter; import java.io.BufferedWriter; import java.io.FileWriter; import java.util.List; public class ArrayToCsvExample { public static void main(String[] args) { String[][] csvData = { {"ID", "Name", "Age"}, {"1", "Alice", "25"}, {"2", "Bob", "30"} }; try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.csv")); CSVWriter writer = new CSVWriter(bw)) { writer.writeAll(List.of(csvData)); } catch (Exception e) { e.printStackTrace(); } } }
性能优化点
- 用
BufferedReader/BufferedWriter包装文件流,减少磁盘IO次数 - 若处理超大文件,不要用
readAll()一次性加载所有数据,改用reader.readNext()逐行读取处理 - 可以通过
CSVParserBuilder自定义分隔符、引号字符等,适配非标准CSV
二、Apache Commons CSV(高性能、功能全面)
Apache Commons CSV支持多种CSV格式规范(如RFC4180),性能比OpenCSV更优,适合处理大文件或复杂格式的CSV。
1. 读取CSV并转换为二维数组
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; import java.io.FileReader; import java.io.Reader; import java.util.ArrayList; import java.util.List; public class CommonsCsvToArrayExample { public static void main(String[] args) { try (Reader reader = new FileReader("data.csv"); CSVParser parser = CSVFormat.DEFAULT .withHeader() // 识别表头 .withSkipHeaderRecord() // 跳过表头行 .parse(reader)) { List<String[]> rowList = new ArrayList<>(); // 逐行迭代,内存占用更低 for (CSVRecord record : parser) { String[] row = new String[record.size()]; for (int i = 0; i < record.size(); i++) { row[i] = record.get(i); } rowList.add(row); } String[][] csvArray = rowList.toArray(new String[0][]); } catch (Exception e) { e.printStackTrace(); } } }
2. 将二维数组写入CSV
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import java.io.FileWriter; import java.io.Writer; public class ArrayToCommonsCsvExample { public static void main(String[] args) { String[][] csvData = { {"ID", "Name", "Age"}, {"1", "Alice", "25"}, {"2", "Bob", "30"} }; try (Writer writer = new FileWriter("output.csv"); CSVPrinter printer = CSVFormat.DEFAULT.print(writer)) { for (String[] row : csvData) { printer.printRecord((Object[]) row); } } catch (Exception e) { e.printStackTrace(); } } }
性能优化点
- 采用迭代器模式逐行读取,避免一次性加载全量数据到内存,适合GB级大文件
- 可以通过
CSVFormat配置是否忽略空行、自定义换行符等,适配复杂场景
三、不推荐的自定义实现(仅适合极简场景)
如果只是处理完全没有转义、引号的简单CSV,可以手写逻辑,但性能和兼容性都不如第三方库:
import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayList; import java.util.List; public class SimpleCsvReader { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("simple.csv"))) { List<String[]> rowList = new ArrayList<>(); String line; br.readLine(); // 跳过表头 while ((line = br.readLine()) != null) { rowList.add(line.split(",")); // 注意:如果字段包含逗号会出错 } String[][] csvArray = rowList.toArray(new String[0][]); } catch (Exception e) { e.printStackTrace(); } } }
注意:这种方式无法处理
"John, Doe"这类包含逗号的字段,也无法处理换行符、引号转义等情况,仅适合测试或极简场景。
通用性能总结
- 优先用第三方库:OpenCSV和Apache Commons CSV都经过大量测试,性能和兼容性远优于手写代码
- 缓冲流必加:所有文件IO都用
BufferedReader/BufferedWriter包装,减少磁盘访问次数 - 大文件流式处理:不要一次性加载全部数据,逐行读取处理,降低内存占用
- 避免频繁对象创建:比如复用临时数组或集合,减少GC开销
内容的提问来源于stack exchange,提问作者DamianBautista
相关产品推荐
相关产品推荐

