[英]Reading a huge csv file and converting to JSON with Java 8
我正在尝试读取包含许多列的csv文件。 第一行始终是csv文件的标题。 我想将csv数据转换为JSON。 我可以将其作为String读取并转换为JSON,但我无法为其分配标头。
例如输入csv看起来像:
first_name,last_name
A,A1
B,B1
C,C1
Stream<String> stream = Files.lines(Paths.get("sample.csv"))
List<String[]> readall = stream.map(l -> l.split(",")).collect(Collectors.toList());
要么
List<String> test1 = readall.stream().skip(0).map(row -> row[1]).collect(Collectors.toList());
使用com.fasterxml.jackson.databind.ObjectMapper的WriteValueAsString只创建没有头的JSON。
我希望输出格式如
{
[{"first_name":"A","last_name":"A1"},{"first_name":"B"....
如何在Java中使用流来准备此JSON格式?
请帮忙。
我将分两步解决这个问题:首先,阅读标题,然后阅读其余部分:
static String[] headers(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine().split(",");
}
}
现在,您可以使用上面的方法,如下所示:
String path = "sample.csv";
// Read headers
String[] headers = headers(path);
List<Map<String, String>> result = null;
// Read data
try (Stream<String> stream = Files.lines(Paths.get(path))) {
result = stream
.skip(1) // skip headers
.map(line -> line.split(","))
.map(data -> {
Map<String, String> map = new HashMap<>();
for (int i = 0; i < data.length; i++) {
map.put(headers[i], data[i]);
}
return map;
})
.collect(Collectors.toList());
}
您可以在第二个map
操作中更改for
循环:
try (Stream<String> stream = Files.lines(Paths.get(path))) {
result = stream
.skip(1) // skip headers
.map(line -> line.split(","))
.map(data -> IntStream.range(0, data.length)
.boxed()
.collect(Collectors.toMap(i -> headers[i], i -> data[i])))
.collect(Collectors.toList());
}
编辑:如果不是收集到列表,而是要对从每行读取的地图执行操作,可以按如下方式执行:
try (Stream<String> stream = Files.lines(Paths.get(path))) {
stream
.skip(1) // skip headers
.map(line -> line.split(","))
.map(data -> IntStream.range(0, data.length)
.boxed()
.collect(Collectors.toMap(i -> headers[i], i -> data[i])))
.forEach(System.out::println);
}
(这里的动作是打印每张地图)。
本版本可以被改善,即,它箱流int
秒,然后unboxes每个int
再次使用它作为的索引headers
和data
阵列。 此外,通过将每个映射的创建提取到私有方法,可以提高可读性。
注意:也许读取文件两次并不是性能最好的方法,但代码简单而富有表现力。 除此之外, null
处理,数据转换(即数字或日期等)和边界情况(即没有标题,没有数据行或数据数组的不同长度等)留给读者练习;)
我想这就是你想要做的
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class App {
public static void main(String[] args) throws JsonProcessingException, IOException {
Stream<String> stream = Files.lines(Paths.get("src/main/resources/test1.csv"));
List<Map<String, Object>> readall = stream.map(l -> {
Map<String, Object> map = new HashMap<String, Object>();
String[] values = l.split(",");
map.put("name", values[0]);
map.put("age", values[1]);
return map;
}).collect(Collectors.toList());
ObjectMapper mapperObj = new ObjectMapper();
String jsonResp = mapperObj.writeValueAsString(readall);
System.out.println(jsonResp);
}
}
使用带有标头的Java -8 Streams,并使用jackson将其转换为json。 使用了CSV
abc,20
bbc,30
非常简单,不要将其转换为字符串列表。 将其转换为HashMaps列表,然后使用org.json库将其转换为json。 使用jackson将CSV转换为Hashmap
让输入流为
InputStream stream = new FileInputStream(new File("filename.csv"));
示例:将CSV转换为HashMap
public List<Map<String, Object>> read(InputStream stream) throws JsonProcessingException, IOException {
List<Map<String, Object>> response = new LinkedList<Map<String, Object>>();
CsvMapper mapper = new CsvMapper();
CsvSchema schema = CsvSchema.emptySchema().withHeader();
MappingIterator<Map<String, String>> iterator = mapper.reader(Map.class).with(schema).readValues(stream);
while (iterator.hasNext())
{
response.add(Collections.<String, Object>unmodifiableMap(iterator.next()));
}
return response;
}
将Map的List转换为Json
JSONArray jsonArray = new JSONArray(response);
System.out.println(jsonArray.toString());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.