{"record":{"id":"ce9d1315f1be1a69","repo":"chinabugotech/hutool","slug":"not-a-file","errorCode":null,"errorMessage":"Not a file: {}","messagePattern":"Not a file: (.+?)","errorType":"exception","errorClass":"IORuntimeException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java","lineNumber":303,"sourceCode":"\t *\n\t * @param <T> Reader处理返回结果类型\n\t */\n\tpublic interface ReaderHandler<T> {\n\t\tT handle(BufferedReader reader) throws IOException;\n\t}\n\t// -------------------------------------------------------------------------- Interface end\n\n\t/**\n\t * 检查文件\n\t *\n\t * @throws IORuntimeException IO异常\n\t */\n\tprivate void checkFile() throws IORuntimeException {\n\t\tif (false == file.exists()) {\n\t\t\tthrow new IORuntimeException(\"File not exist: \" + file);\n\t\t}\n\t\tif (false == file.isFile()) {\n\t\t\tthrow new IORuntimeException(\"Not a file:\" + file);\n\t\t}\n\t}\n}\n","sourceCodeStart":285,"sourceCodeEnd":307,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/io/file/FileReader.java#L285-L307","documentation":"FileReader.checkFile() (called from the constructor) throws 'Not a file' when the File exists but file.isFile() is false, i.e. it is a directory or a non-regular (device/special) file. FileReader is designed to read regular files only and intentionally refuses directories. Like the not-exist check, this fires at construction time, before any read.","triggerScenarios":"Constructing a FileReader (new FileReader(path) or FileReader.create(file)) where the path resolves to an existing directory, or to a non-regular file. Common when a folder path is passed where a file path was expected, or when a trailing slash / trailing segment makes the path a directory.","commonSituations":"Passing a directory path instead of a file path; misconfigured path that resolves to a folder; intending to read one file inside a directory but pointing at the directory itself; OS path differences where the same name is a directory on one platform.","solutions":["Point the FileReader at a specific regular file, not a directory.","If you meant to read files inside a directory, list the entries (FileUtil.list / Files.list) and read each regular file individually.","Validate with Files.isRegularFile(path) before constructing the reader."],"exampleFix":"// before: 'logs' is a directory -> 'Not a file'\nFileReader reader = FileReader.create(new File(\"/var/log/myapp\"));\n\n// after: target a specific file inside the directory\nFile target = new File(\"/var/log/myapp\", \"app.log\");\nif (!target.isFile()) {\n    throw new IllegalStateException(\"Expected a regular file: \" + target);\n}\nFileReader reader = FileReader.create(target);","handlingStrategy":"validation","validationCode":"Path p = Paths.get(pathArg);\nif (!Files.isRegularFile(p)) {\n    throw new IllegalArgumentException(\n        \"Expected a regular file but got: \" + p\n        + (Files.isDirectory(p) ? \" (it is a directory)\" : \"\"));\n}\nFileReader reader = FileReader.create(p.toFile());","typeGuard":"boolean isRegularReadableFile(String path) {\n    File f = new File(path);\n    return f.isFile(); // true only for existing regular files\n}","tryCatchPattern":"try {\n    FileReader reader = FileReader.create(file);\n} catch (IORuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Not a file\")) {\n        // user pointed at a directory/special file\n        if (file.isDirectory()) {\n            // iterate entries and read each regular file\n        }\n    }\n    throw e;\n}","preventionTips":["Always pass a specific file path, not a directory, to FileReader.","Validate Files.isRegularFile before constructing a reader.","When accepting user input, reject directory paths early with a clear message.","For directory reads, list entries first and read each regular file individually."],"tags":["io","filesystem","path","directory","hutool"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}