我有一个传统的文件系统。 数据文件大小为4 GB,看起来像
ID,姓名,角色,部门
1,Patrick,2,3,
2,伊曼纽尔,1,5,
3,Mike,1,5,
我必须将文件转换为:
ID,姓名,角色,部门
1,帕特里克,操作员,研磨
2,伊曼纽尔,助理,人力资源
3,迈克,助理,人力资源以上数据需要保存到另一个文件中。
避免OutOfMemory异常的最佳方法是什么?
我知道我需要使用像Scanner这样的东西来读取文件,但是如何将中间输出(转换后的数据)存储在类似Map的对象中,这会通过累加每行数据而大大增加?
答案 0 :(得分:0)
如果您确实需要使用Java,请尝试将其加载到H2数据库中:
CREATE TABLE TEST AS SELECT * FROM CSVREAD('test.csv');
然后,您可以使用SQL转换表并将其写入另一个CSV:
CALL CSVWRITE('test2.csv', 'SELECT * FROM TEST2');
答案 1 :(得分:0)
使用正确(快速)的CSV解析器。使用univocity-parsers整个过程应该需要几秒钟。
首先创建一个RowProcessor
,它将接收从输入解析的每一行,转换它并将结果写入给定的输出。
public RowProcessor createProcessor(final File output){
CsvWriterSettings outputSettings = new CsvWriterSettings();
//configure the CSV writer - format and other settings.
//create a writer for the output you want with the given settings.
final CsvWriter writer = new CsvWriter(output, "UTF-8", outputSettings);
return new com.univocity.parsers.common.processor.RowProcessor(){
private Map<String, String> roleMap;
private Map<String, String> deptMap;
@Override
public void processStarted(ParsingContext context) {
roleMap = buildMapOfRoles();
deptMap = buildMapOfDepartments();
}
@Override
public void rowProcessed(String[] row, ParsingContext context) {
row[2] = roleMap.get(row[2]);
row[3] = deptMap.get(row[3]);
writer.writeRow(row);
}
@Override
public void processEnded(ParsingContext context) {
writer.close();
}
};
}
然后运行解析器:
String encoding = "UTF-8";
File input = new File("/path/to/input.csv");
File output = new File("/path/to/output.csv");
RowProcessor processor = createProcessor(output, encoding);
CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setProcessor(processor);
//configure the parser settings as needed.
//then run the parser. It will submit all rows to the processor created above.
new CsvParser(parserSettings).parse(input, encoding);
所有行都将提交给您的processor
并将转换后的行直接写入输出
以下是我buildMapOfRoles
和buildMapOfDepartments
的精彩实现:
private Map<String, String> buildMapOfRoles(){
Map<String,String> out = new HashMap<>();
out.put("2", "Operator");
out.put("1", "Assistant");
return out;
}
private Map<String, String> buildMapOfDepartments(){
Map<String,String> out = new HashMap<>();
out.put("3", "Grinding");
out.put("5", "HR");
return out;
}
这将产生您期望的确切输出。希望这有帮助
免责声明:我是这个图书馆的作者。它的开源和免费(Apache 2.0许可证)