由于最近公司项目涉及到将xml内容显示在word表格中的业务需求,这就需要调用方将xml内容作为请求内容传递给生成接口。但在开发中发现没有得到预期效果,这是由于xml内容并未传入导致的,最后经过调查发现,当xml中写入多个图片,xml无法保存在数据库中。
对于该问题需要考虑多个方面来解决:
1、首先之所以未保存成功,是因为出现413错误请求体过大引起,最简单的方式就是增大请求上限,允许更大的请求体。如果条件允许,更加推荐使用图片服务器来单独存储图片,在xml中图片使用url或id来表示,这样可以有效降低请求体大小。
2、解决了请求过大的问题后,由于在程序中xml是使用字符串来处理并存储在数据库中,还要防止字符串太大的问题。这是因为java在设计时String是有大小限制的,所以更推荐使用流来分块处理大文本内容。
原因:字符串会将整个文本一次性加载到内存中,如果处理的是GB级文件,可能导致内存溢出(OOM)。示例:加载一个1GB的文本文件到字符串,至少需要1GB内存(实际更高,因字符编码和对象开销)
流通过分块(Chunk)处理逐段读写数据,避免一次性加载全部内容。需要注意的是:流的真正优势在于处理外部数据源时逐步加载内容,而非处理已加载到内存的字符串。例如:1. 从文件流式读取
分块加载:每次读取固定大小(如64KB)的分块。
const fs = require('fs');
const readStream = fs.createReadStream('large_file.txt', { highWaterMark: 64 * 1024 });
// 内存占用始终 ≤ 64KB
2、动态生成数据
逐步生成内容:如实时日志、数据库查询结果流式返回。
const { Readable } = require('stream');
const stream = new Readable({
read(size) {
// 按需生成数据,每次最多生成size字节
this.push(generateDataChunk(size));
}
});
在处理字符串时,如果将整个字符串一次性转换为流且不分块处理,其内存占用与直接使用字符串几乎相同,甚至可能略高(因流对象本身有额外开销)。
3、数据库存储使用text或byte。更推荐使用byte存储可以节约内存。
总结:
- 字符串直接处理:适用于小文本(如 < 10MB),简单但内存占用高,若必须处理大文本,使用 StringBuilder 分段构建。
- 流处理的核心价值: (1)外部数据源分块加载(如文件、网络)。 (2)动态生成数据分块(避免一次性内存占用)。
错误用法:将已有大字符串转为流且不分块——内存无优化,反而增加流对象开销。
最终建议:若数据已以字符串形式存在于内存中,直接处理即可;若需处理外部或动态生成的大数据,务必使用分块流式处理。