使用Java合并100+JSON文件时for循环动态命名JSONArray问题求解
Java批量合并上百个结构相似JSONArray实现方案
现有代码核心问题
- 不需要实现所谓「循环内动态设置JSONArray变量名」的逻辑,这类批量处理场景完全用不上动态变量。现有代码无法完成合并的核心原因是存储最终结果的数组被定义在了for循环内部,每次循环都会重新初始化为空数组,根本不会累计之前读取到的文件内容
- 流资源关闭逻辑错误:实际读取文件用的是
BufferedReader br,finally块却只关闭了从未初始化的fileInputStream,会造成文件句柄泄漏 - JSON解析逻辑冗余:如果单个json文件存储的本身就是JSONArray内容,直接用JSONTokener解析为JSONArray即可,不需要先转JSONObject再强转
- 循环范围不匹配:现有写法
j<10仅会读取1-9共9个文件,要处理上百个文件直接调整循环终止条件即可
修正后可直接运行的代码
import org.json.*; import java.io.*; import java.nio.charset.StandardCharsets; public class JsonArrayBatchMerge { public static void main(String[] args) throws IOException { // 合并结果数组定义在循环外,全局唯一,全程累计所有文件的数组元素 JSONArray mergedResultArray = new JSONArray(); // 按实际文件总数调整循环上限,比如要读1-126号文件就设置为127 int totalFileNum = 127; BufferedReader br = null; for (int fileIndex = 1; fileIndex <= totalFileNum; fileIndex++) { String currentFilePath = "c:/test1/jsonparser" + fileIndex + ".json"; StringBuilder contentBuilder = new StringBuilder(); try { br = new BufferedReader(new InputStreamReader( new FileInputStream(currentFilePath), StandardCharsets.UTF_8)); int charCode; while ((charCode = br.read()) != -1) { contentBuilder.append((char) charCode); } String fileContent = contentBuilder.toString(); JSONArray currentFileArray; // 两种解析场景二选一即可 // 场景1:单文件本身就是纯JSONArray,用下面这行 currentFileArray = new JSONArray(new JSONTokener(fileContent)); // 场景2:单文件是JSONObject,数组挂在固定key下(比如key为data),注释掉上一行,用下面两行 // JSONObject currentFileObj = new JSONObject(new JSONTokener(fileContent)); // currentFileArray = currentFileObj.getJSONArray("data"); // 把当前文件数组的所有元素追加到全局结果数组 for (int i = 0; i < currentFileArray.length(); i++) { mergedResultArray.put(currentFileArray.get(i)); } } catch (Exception e) { e.printStackTrace(); } finally { // 正确关闭实际使用的流资源 if (br != null) { br.close(); } } } // 循环结束后mergedResultArray就是所有文件合并后的完整结果,可直接输出或写入目标文件 String finalResult = mergedResultArray.toString(); System.out.println(finalResult); } }
实现说明
- 不要被动态变量的思路带偏:Java本身没有原生的动态变量名语法,这类批量文件处理场景,只需要在循环外维护一个全局结果容器,循环内逐个读取文件内容、解析后追加到容器即可,不需要给每个文件的JSONArray单独分配变量名
- 如果使用JDK11及以上版本,可以直接用
Files.readString(Paths.get(currentFilePath), StandardCharsets.UTF_8)读取整个文件内容,替换掉逐字符拼接的逻辑,代码更简洁、读取性能更好 - 如果需要后续溯源元素来源,可以在追加每个JSONObject时,额外添加一个字段记录对应的来源文件名
内容的提问来源于stack exchange,提问作者SorokinHutor
相关产品推荐
相关产品推荐

