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).
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
- File length is [ ] but read [ ]!
- File not exist
- Not a file
- Src [ ] is a directory but dest [ ] is a file!
- Can not read file path of
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/ad42ffb455571854.
Report an issue: GitHub.
Appendix: 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)