Spring Boot写入JSON文件达大小阈值时动态滚动创建新文件方案
问题描述
我有一个Spring Boot应用,会持续向指定路径下的文本文件写入JSON数据,需要实现文件大小达到上限时,自动动态创建新文件继续写入的能力。
最初我考虑通过手动编码实现上述逻辑,示例代码如下:
for (int i = 1; i < 1000; i++) { try { File f = new File(FILE_LOCATION + fileName); fileSize = Files.size(f.toPath()); System.out.println("filesize: " + fileSize); if (f.exists()) { if (fileSize > SIZE_1KB) { writer = new FileWriter(FILE_LOCATION + "00" + i + ".txt"); fileName = "00" + i + ".txt"; } else { writer = new FileWriter(FILE_LOCATION + fileName, true); } } else { writer = new FileWriter(FILE_LOCATION + fileName); } // 写入数据逻辑 if (f.exists()) { for (int j = 0; j < 10; j++) writer.append(UUID.randomUUID().toString()); } else { for (int j = 0; j < 10; j++) writer.write(UUID.randomUUID().toString()); } } catch (Exception e) { e.printStackTrace(); } }
说明:以上仅为提问时编写的示例代码,Spring Boot应用中实际使用的文件写入逻辑与该示例逻辑基本一致。
手动实现方案需要自行处理大量配套逻辑:除了文件大小达到阈值时创建新文件外,还需要实现日期变更时将旧文件移动至归档目录、归档目录大小达到上限时自动删除老旧归档文件等能力。
我也调研过logback.xml配置方案,但该配置已被用于业务日志文件的滚动输出,无法复用到当前JSON数据写入场景。
手动编码实现所有逻辑成本较高,需要更成熟的实现方式,包括适配的开源库、框架或最佳实践推荐。
方案进展更新
更新1
我找到了rotating-fos库,正在调试对应配置,希望满足按文件大小滚动、按日期滚动、存储阈值达标时删除旧文件的通用需求。
更新2
目前已经通过rotating-fos库实现了除旧文件删除外的所有上述需求。由于业务场景中,生成的文本文件会通过独立流程推送至数据管道,后续由该流程负责文件的删除操作,当前落地实现代码如下:
private void processEntry(Map<String, Object> entry) { try { String path = jsonProcessingPath + "/" + CALL_DATA + "/"; SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT); File dir = new File(path + format.format(new Date())); if (!dir.exists()) dir.mkdir(); String fileName = CALL_DATA_FILE_NAME; File file = new File(dir.getAbsolutePath() + "//" + fileName); if (!file.exists()) file.createNewFile(); RotationConfig config = RotationConfig.builder().file(file.getAbsolutePath()) .filePattern(dir + "/" + CALL_DATA_FILE_NAME + ".%d{HHmmss}.txt") .policy(new SizeBasedRotationPolicy(Long.parseLong(SIZE_LIMIT))) .policy(DailyRotationPolicy.getInstance()).build(); RotatingFileOutputStream outputStream = new RotatingFileOutputStream(config); Gson gson = new Gson(); String json = gson.toJson(entry); int currentId = gson.fromJson(json, JsonObject.class).get(ID).getAsInt(); log.debug("Writing entry of report_data_calls table"); outputStream.write(json.getBytes()); outputStream.close(); exampleSchedulerService.updateJobDataMapInfo(ProcessCallDataJob.class, CALL_DATA_LAST_ID, currentId); log.debug("Updated last processed call id to be: " + currentId); } catch (Exception e) { log.error("error: {}", e); } }
内容的提问来源于stack exchange,提问作者Akki
相关产品推荐
相关产品推荐

