{"record":{"id":"8f3377e01aadb4f9","repo":"chinabugotech/hutool","slug":"input-must-be-a-file","errorCode":null,"errorMessage":"Input must be a File","messagePattern":"Input must be a File","errorType":"exception","errorClass":"IORuntimeException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java","lineNumber":587,"sourceCode":"\t * @since 5.8.28\n\t */\n\tpublic static int getTotalLines(File file, int bufferSize) {\n\t\treturn getTotalLines(file, bufferSize, true);\n\t}\n\n\t/**\n\t * 计算文件的总行数<br>\n\t * 参考：https://stackoverflow.com/questions/453018/number-of-lines-in-a-file-in-java\n\t *\n\t * @param file       文件\n\t * @param bufferSize 缓存大小，小于1则使用默认的1024\n\t * @param lastLineSeparatorAsNewLine 是否将最后一行分隔符作为新行，Linux下要求最后一行必须带有换行符，不算一行，此处用户选择\n\t * @return 该文件总行数\n\t * @since 5.8.37\n\t */\n\tpublic static int getTotalLines(File file, int bufferSize, boolean lastLineSeparatorAsNewLine) {\n\t\tif (false == isFile(file)) {\n\t\t\tthrow new IORuntimeException(\"Input must be a File\");\n\t\t}\n\t\tif (bufferSize < 1) {\n\t\t\tbufferSize = 1024;\n\t\t}\n\t\ttry (InputStream is = getInputStream(file)) {\n\t\t\tbyte[] chars = new byte[bufferSize];\n\t\t\tint readChars = is.read(chars);\n\t\t\tif (readChars == -1) {\n\t\t\t\t// 空文件，返回0\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\t// 起始行为1\n\t\t\t// 如果只有一行，无换行符，则读取结束后返回1\n\t\t\t// 如果多行，最后一行无换行符，最后一行需要单独计数\n\t\t\t// 如果多行，最后一行有换行符，则空行算作一行\n\t\t\tint count = 1;\n\t\t\tbyte pre;","sourceCodeStart":569,"sourceCodeEnd":605,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java#L569-L605","documentation":"FileUtil.getTotalLines(File, int, boolean) counts lines by buffering reads. It requires a real, existing regular file; if isFile() is false (directory or missing) it throws IORuntimeException(\"Input must be a File\").","triggerScenarios":"Calling FileUtil.getTotalLines(...) with a File that is a directory or does not exist.","commonSituations":"Passing a directory path by mistake; file deleted between an existence check and the call; counting lines on a path for a file that has not been written yet.","solutions":["Guard with FileUtil.isFile(file) before counting.","Ensure the file is created and flushed before calling getTotalLines.","Double-check the path spelling and that it is not a folder."],"exampleFix":"// before\nint n = FileUtil.getTotalLines(file, 1024, false); // throws if dir/missing\n\n// after\nif (FileUtil.isFile(file)) {\n    int n = FileUtil.getTotalLines(file, 1024, false);\n}","handlingStrategy":"validation","validationCode":"if (FileUtil.isFile(file)) {\n    int lines = FileUtil.getTotalLines(file, bufferSize, lastLineSeparatorAsNewLine);\n}","typeGuard":"static boolean isCountableFile(File f) {\n    return f != null && f.isFile();\n}","tryCatchPattern":"try {\n    return FileUtil.getTotalLines(file, 1024, false);\n} catch (IORuntimeException e) {\n    // not a readable file: return -1 or report\n}","preventionTips":["Guard with FileUtil.isFile() before counting lines.","Ensure the file is written and closed before counting.","Do not pass directory paths to line-counting APIs."],"tags":["io","file","validation"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}