{"record":{"id":"ad42ffb455571854","repo":"chinabugotech/hutool","slug":"file-is-larger-then-max-array-size","errorCode":null,"errorMessage":"File is larger then max array size","messagePattern":"File is larger then max array size","errorType":"exception","errorClass":"IORuntimeException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java","lineNumber":116,"sourceCode":"\t * 编码使用 {@link FileWrapper#DEFAULT_CHARSET}\n\t * @param filePath 文件路径，相对路径会被转换为相对于ClassPath的路径\n\t */\n\tpublic FileReader(String filePath) {\n\t\tthis(filePath, DEFAULT_CHARSET);\n\t}\n\t// ------------------------------------------------------- Constructor end\n\n\t/**\n\t * 读取文件所有数据<br>\n\t * 文件的长度不能超过 {@link Integer#MAX_VALUE}\n\t *\n\t * @return 字节码\n\t * @throws IORuntimeException IO异常\n\t */\n\tpublic byte[] readBytes() throws IORuntimeException {\n\t\tlong len = file.length();\n\t\tif (len >= Integer.MAX_VALUE) {\n\t\t\tthrow new IORuntimeException(\"File is larger then max array size\");\n\t\t}\n\n\t\tbyte[] bytes = new byte[(int) len];\n\t\tFileInputStream in = null;\n\t\tint readLength;\n\t\ttry {\n\t\t\tin = new FileInputStream(file);\n\t\t\treadLength = in.read(bytes);\n\t\t\tif(readLength < len){\n\t\t\t\tthrow new IOException(StrUtil.format(\"File length is [{}] but read [{}]!\", len, readLength));\n\t\t\t}\n\t\t} catch (Exception e) {\n\t\t\tthrow new IORuntimeException(e);\n\t\t} finally {\n\t\t\tIoUtil.close(in);\n\t\t}\n\n\t\treturn bytes;","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java#L98-L134","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":"// before: loads the entire file into a byte[] / String -> fails for >= 2 GiB\nbyte[] data = FileReader.create(bigFile).readBytes();\nString text = FileReader.create(bigFile).readString();\n\n// after: stream the file instead of materializing it\nFileReader.create(bigFile).readLines((String line) -> {\n    // process one line at a time, constant memory\n});","handlingStrategy":"validation","validationCode":"File f = ...;\nif (f.length() >= Integer.MAX_VALUE) {\n    // do NOT call readBytes()/readString(); stream instead\n    try (InputStream in = new BufferedInputStream(new FileInputStream(f))) {\n        // process in chunks\n    }\n    return;\n}\nbyte[] data = FileReader.create(f).readBytes();","typeGuard":"boolean canReadIntoArray(File f) {\n    return f != null && f.isFile() && f.length() < Integer.MAX_VALUE;\n}","tryCatchPattern":"try {\n    byte[] data = FileReader.create(f).readBytes();\n} catch (IORuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"larger then max array size\")) {\n        // fall back to a streaming reader instead of materializing\n        FileReader.create(f).readLines(line -> handle(line));\n    } else {\n        throw e;\n    }\n}","preventionTips":["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."],"tags":["io","memory","large-files","hutool","array-limit"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}