java - StringBuilder.append 内存不足
问题描述
我正在使用 StringBuilder.append() 来解析和处理文件,如下所示:
StringBuilder csvString = new StringBuilder();
bufferedReader.lines().filter(line -> !line.startsWith(HASH) && !line.isEmpty()).map(line -> line.trim())
.forEachOrdered(line -> csvString.append(line).append(System.lineSeparator()));
int startOfFileTagIndex = csvString.indexOf(START_OF_FILE_TAG);
int startOfFieldsTagIndex = csvString.indexOf(START_OF_FIELDS_TAG, startOfFileTagIndex);
int endOfFieldsTagIndex = csvString.indexOf(END_OF_FIELDS_TAG, startOfFieldsTagIndex);
int startOfDataTagIndex = csvString.indexOf(START_OF_DATA_TAG, endOfFieldsTagIndex);
int endOfDataTagIndex = csvString.indexOf(END_OF_DATA_TAG, startOfDataTagIndex);
int endOfFileTagIndex = csvString.indexOf(END_OF_FILE_TAG, endOfDataTagIndex);
int timeStartedIndex = csvString.indexOf("TIMESTARTED", endOfFieldsTagIndex);
int dataRecordsIndex = csvString.indexOf("DATARECORDS", endOfDataTagIndex);
int timeFinishedIndex = csvString.indexOf("TIMEFINISHED", endOfDataTagIndex);
if (startOfFileTagIndex != 0 || startOfFieldsTagIndex == -1 || endOfFieldsTagIndex == -1
|| startOfDataTagIndex == -1 || endOfDataTagIndex == -1 || endOfFileTagIndex == -1) {
log.error("not in correct format");
throw new Exception("not in correct format.");
}
问题是当文件很大时,我得到一个内存不足的异常。你能帮我转换我的代码以避免大文件的异常吗?
编辑:据我所知,将一个大文件充电到一个字符串 Builder 不是一个好主意,也不会工作。所以问题是Java中的哪个结构更适合用来解析我的大文件,删除一些行,找到一些行的索引并将文件分成几部分(在哪里存储这些部分可能很大)根据找到索引然后最后创建一个输出文件?
解决方案
OOM 似乎是由于您将所有行都存储在StringBuilder
. 当文件行数过多时,会占用大量内存,可能导致OOM。
避免这种情况的策略取决于您对附加字符串所做的操作。正如我在您的代码中看到的,您只是在尝试验证输入文件的结构。在这种情况下,您不需要将所有行存储在一个StringBuilder
实例中。反而,
- 有多个
int
s 来保存您感兴趣的每个索引,(或有一个int
s 数组) - 不要将行添加到 中
StringBuilder
,而是检测您正在寻找的“标签”或“索引”的存在并将其保存在其指定的int
变量中。 - 最后,您已经在做的检查可能需要进行更改以测试不是
-1
相对于其他指数而是相对于其他指数。(您当前正在使用indexOf()
调用中的开始索引来实现这一点。) - 如果标签存在跨行的风险,那么您可能无法使用流,但必须使用一个简单的
for
循环来保存一些先前的行,附加它们并检查。(只有一个想法;您可能有更好的想法。)
推荐阅读
- excel - 从excel粘贴图片后,将默认签名添加到电子邮件正文
- javascript - ExpressJS 视频流有烦人的音频问题
- python-3.x - bootstrap4 / prev 或 next btn 的烧瓶分页未显示
- google-sheets - 在 Google 表格中使用单元格值作为工作表名称以供参考
- kubernetes - 无法在具有持久卷的 kubernetes 上运行 oracle 数据库 12
- python - 如何在for循环的每次迭代中获取2组键值对?
- javascript - Expo后台权限异步不起作用
- python - TensorFlow 分割错误
- c# - Dawn.Guard 成员验证抛出 ArgumentException
- python - 如何使用 Web3py 获取特定合约的 ERC20 代币交易