chinabugotech/hutool · error · IORuntimeException
File is larger then max array size
Error message
File is larger then max array size
What it means
FileReader.readBytes() refuses to load any file whose length() >= Integer.MAX_VALUE (~2.147 GiB). Java arrays are int-indexed and cannot hold that many bytes, so the allocation new byte[(int) len] would either fail or trigger OOM/NegativeArraySizeException. Hutool throws proactively with this message instead of attempting the doomed allocation. Because readString() delegates to readBytes(), the same limit applies to readString() and to convenience wrappers like FileUtil.readBytes(File).
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java:116
* 编码使用 {@link FileWrapper#DEFAULT_CHARSET}
* @param filePath 文件路径,相对路径会被转换为相对于ClassPath的路径
*/
public FileReader(String filePath) {
this(filePath, DEFAULT_CHARSET);
}
// ------------------------------------------------------- Constructor end
/**
* 读取文件所有数据<br>
* 文件的长度不能超过 {@link Integer#MAX_VALUE}
*
* @return 字节码
* @throws IORuntimeException IO异常
*/
public byte[] readBytes() throws IORuntimeException {
long len = file.length();
if (len >= Integer.MAX_VALUE) {
throw new IORuntimeException("File is larger then max array size");
}
byte[] bytes = new byte[(int) len];
FileInputStream in = null;
int readLength;
try {
in = new FileInputStream(file);
readLength = in.read(bytes);
if(readLength < len){
throw new IOException(StrUtil.format("File length is [{}] but read [{}]!", len, readLength));
}
} catch (Exception e) {
throw new IORuntimeException(e);
} finally {
IoUtil.close(in);
}
return bytes;View on GitHub (pinned to 8870454b2a)
Solutions
- Switch to a streaming API that never materializes the whole file: FileReader.readLines(LineHandler), FileReader.getInputStream(), FileReader.writeToStream(out), or FileUtil.readUtf8Lines.
- If you need the bytes, read in chunks via an InputStream and accumulate into a growable structure, stopping short of the limit.
- Pre-filter or split the file so each part stays under 2 GiB.
- For huge text, process line-by-line with readLines() instead of readString().
Example fix
// before: loads the entire file into a byte[] / String -> fails for >= 2 GiB
byte[] data = FileReader.create(bigFile).readBytes();
String text = FileReader.create(bigFile).readString();
// after: stream the file instead of materializing it
FileReader.create(bigFile).readLines((String line) -> {
// process one line at a time, constant memory
}); Defensive patterns
Strategy: validation
Validate before calling
File f = ...;
if (f.length() >= Integer.MAX_VALUE) {
// do NOT call readBytes()/readString(); stream instead
try (InputStream in = new BufferedInputStream(new FileInputStream(f))) {
// process in chunks
}
return;
}
byte[] data = FileReader.create(f).readBytes(); Type guard
boolean canReadIntoArray(File f) {
return f != null && f.isFile() && f.length() < Integer.MAX_VALUE;
} Try / catch
try {
byte[] data = FileReader.create(f).readBytes();
} catch (IORuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("larger then max array size")) {
// fall back to a streaming reader instead of materializing
FileReader.create(f).readLines(line -> handle(line));
} else {
throw e;
}
} Prevention
- Never call readBytes()/readString() on unbounded user-supplied or log files.
- Prefer streaming APIs (readLines, getInputStream, writeToStream) for anything that may grow large.
- Enforce a max-file-size check before reads in request/file-upload handlers.
- Monitor file sizes in long-running services so growth past 2 GiB is caught early.
When it happens
Trigger: Calling FileReader.readBytes() or readString() (or FileUtil wrappers that delegate to them) on a file whose reported length is at least Integer.MAX_VALUE bytes. The check compares file.length() >= Integer.MAX_VALUE, so any file >= 2,147,483,647 bytes triggers it before any I/O begins.
Common situations: Loading large log files, media/video files, database dumps, VM disk images, or build artifacts that grew past 2 GiB; reading a huge archive fully into memory; unbounded log/CSV growth in a long-running service; tests reading a generated fixture that exceeded the limit.
Related errors
- Src [{}] is a directory but dest [{}] is a file!
- File length is [{}] but read [{}]!
- File not exist: {}
- Not a file: {}
- TTS请求失败:
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/ad42ffb455571854.
Report an issue: GitHub.