Java处理CSV或者制表符等分隔文件,比如Maf文件
引入POM的依赖maven
<dependency>
<groupId>com.univocity</groupId>
<artifactId>univocity-parsers</artifactId>
<version>2.9.1</version>
</dependency>
如果没有lombok
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
代码(main函数内是其他业务,请勿直接参考):
import com.univocity.parsers.common.processor.RowListProcessor;
import com.univocity.parsers.csv.CsvParser;
import com.univocity.parsers.csv.CsvParserSettings;
import lombok.Data;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Optional;
/**
* @ClassName UnivocityReadCsv
* @Desc 使用Univocity解析CSV文件
* @Author lanluyu
* @Date 2022-08
**/
public class UnivocityReadCsv {
public Entity parseCSV(String fileName){
//创建一个配置选项,用来提供多种配置选项
CsvParserSettings parserSettings = new CsvParserSettings();
//打开解析器的自动检测功能,让它自动检测输入中包含的分隔符
parserSettings.setLineSeparatorDetectionEnabled(true);
parserSettings.setMaxCharsPerColumn(10000);
//以\t为分隔符,默认以逗号作为分隔符
parserSettings.setDelimiterDetectionEnabled(true, '\t');
//创建RowListProcessor对象,用来把每个解析的行存储在列表中
RowListProcessor rowListProcessor = new RowListProcessor();
parserSettings.setProcessor(rowListProcessor); //配置解析器
//待解析的CSV文件包含标题头,把第一个解析行看作文件中每个列的标题
parserSettings.setHeaderExtractionEnabled(true);
parserSettings.setLineSeparatorDetectionEnabled(true);
//创建CsvParser对象,用于解析文件
CsvParser parser = new CsvParser(parserSettings);
parser.parse(new File(fileName));
//如果解析中包含标题,用于获取标题
String[] headers = rowListProcessor.getHeaders();
//获取行值,并遍历打印
List<String[]> rows = rowListProcessor.getRows();
return new Entity(rows, headers);
}
@Data
static class Entity{
List<String[]> rows;
String[] headers;
public Entity(List<String[]> rows, String[] headers){
this.rows = rows;
this.headers = headers;
}
}
public static void main(String[] args) throws IOException {
UnivocityReadCsv readCsv = new UnivocityReadCsv();
Entity entity = readCsv.parseCSV("C:\\wx\\WeChat Files\\zongzhihui832496\\FileStorage\\File\\2022-08\\input.maf");
String[] headers = entity.getHeaders();
List<String[]> rows = entity.getRows();
File file = new File("result.maf");
for (int i = 0; i < headers.length; i++) {
if(i == 0) Files.write(file.toPath(), headers[0].getBytes(StandardCharsets.UTF_8));
else Files.write(file.toPath(), headers[i].getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
}
Files.write(file.toPath(), "\n".getBytes(), StandardOpenOption.APPEND);
Path path = file.toPath();
for (String[] strings : rows) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < strings.length; j++) {
if (j == 15) {
sb.append(strings[15], 0, 12);
} else {
sb.append(Optional.ofNullable(strings[j]).orElse(""));
}
if (j != strings.length - 1) {
sb.append("\t");
}
}
sb.append("\n");
Files.write(path, sb.toString().getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
}
}
}
说明:一般来说,maf文件是以\t作为分隔符,且前面包含一些说明信息,需要先移除:
后面都是结构化数据,可以用上面脚本解析