Java中用BufferedReader逐行读取JSON Lines文件是高效做法,需确保每行是独立合法JSON对象,配合Jackson ObjectMapper逐行解析并捕获异常处理错误行。
Java 中用 BufferedReader 逐行读取大型 JSON 行协议(JSON Lines / NDJSON)数据是常见且高效的做法。关键在于:每一行是一个独立、合法的 JSON 对象,不能把整个文件当做一个大 JSON 解析,而要按行切割后分别解析。
确保你的文件确实是 JSON Lines 格式(即每行一个 JSON 对象,无换行、无逗号分隔、不包裹在数组中)。例如:
{ "id": 1, "name": "Alice"}{"id": 2, "name": "Bob"}{"id": 3, "name": "Charlie"}
✅ 正确示例(每行独立、合法 JSON):
{"user":"u1","event":"login","ts":1712345678}
{"user":"u2","event":"logout","ts":1712345689}
{"user":"u3","event":"click","ts":1712345695}
❌ 错误示例(整体是 JSON 数组或含多行对象):
[{"id":1},{"id":2}] 或跨行未闭合的 JSON —— 这种不能用逐行解析。
推荐搭配 Jackson 的 ObjectMapper,它支持解析单个 JSON 字符串为 Java 对象。步骤如下:
Files.newBufferedReader() 或 new BufferedReader(new FileReader()) 打开文件readLine(),跳过空行和纯空白行ObjectMapper.readValue(line, YourClass.class) 解析JsonProcessingException 处理格式错误的行(如日志记录 + 跳过)示例代码片段:
立即学习“Java免费学习笔记(深入)”;
ObjectMapper mapper = new ObjectMapper();try (BufferedReader reader = Files.newBufferedReader(Paths.get("data.jsonl"))) { String line; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.isEmpty()) continue; try { MyEvent event = mapper.readValue(line, MyEvent.class); // 处理 event... } catch (JsonProcessingException e) { System.err.println("Invalid JSON line: " + line); } }}
逐行读取本身内存友好,但仍有细节影响稳定性:
readLine() 内部扩容开销StringBuilder 拼接所有行——这会退化为全量加载,失去流式优势BufferedReader 关闭,防止句柄泄漏ObjectReader(mapper.readerFor(MyEvent.class))提升速度如果项目已用 Gson,同样适用:
Gson gson = new Gson();MyEvent event = gson.fromJson(line, MyEvent.class);
若只需提取个别字段(如只取 "id" 和 "ts"),且不想引入完整 POJO,可用 Jackson 的 JsonNode 或 Gson 的 JsonObject 做轻量解析:
JsonNode node = mapper.readTree(line);long id = node.get("id").asLong();String user = node.get("user").asText();
这种方式免写类、灵活,适合 ETL 或日志分析类场景。