chinabugotech/hutool · error · IORuntimeException

Input must be a File

Error message

Input must be a File

What it means

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").

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java:587

	 * @since 5.8.28
	 */
	public static int getTotalLines(File file, int bufferSize) {
		return getTotalLines(file, bufferSize, true);
	}

	/**
	 * 计算文件的总行数<br>
	 * 参考:https://stackoverflow.com/questions/453018/number-of-lines-in-a-file-in-java
	 *
	 * @param file       文件
	 * @param bufferSize 缓存大小,小于1则使用默认的1024
	 * @param lastLineSeparatorAsNewLine 是否将最后一行分隔符作为新行,Linux下要求最后一行必须带有换行符,不算一行,此处用户选择
	 * @return 该文件总行数
	 * @since 5.8.37
	 */
	public static int getTotalLines(File file, int bufferSize, boolean lastLineSeparatorAsNewLine) {
		if (false == isFile(file)) {
			throw new IORuntimeException("Input must be a File");
		}
		if (bufferSize < 1) {
			bufferSize = 1024;
		}
		try (InputStream is = getInputStream(file)) {
			byte[] chars = new byte[bufferSize];
			int readChars = is.read(chars);
			if (readChars == -1) {
				// 空文件,返回0
				return 0;
			}

			// 起始行为1
			// 如果只有一行,无换行符,则读取结束后返回1
			// 如果多行,最后一行无换行符,最后一行需要单独计数
			// 如果多行,最后一行有换行符,则空行算作一行
			int count = 1;
			byte pre;

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Guard with FileUtil.isFile(file) before counting.
  2. Ensure the file is created and flushed before calling getTotalLines.
  3. Double-check the path spelling and that it is not a folder.

Example fix

// before
int n = FileUtil.getTotalLines(file, 1024, false); // throws if dir/missing

// after
if (FileUtil.isFile(file)) {
    int n = FileUtil.getTotalLines(file, 1024, false);
}
Defensive patterns

Strategy: validation

Validate before calling

if (FileUtil.isFile(file)) {
    int lines = FileUtil.getTotalLines(file, bufferSize, lastLineSeparatorAsNewLine);
}

Type guard

static boolean isCountableFile(File f) {
    return f != null && f.isFile();
}

Try / catch

try {
    return FileUtil.getTotalLines(file, 1024, false);
} catch (IORuntimeException e) {
    // not a readable file: return -1 or report
}

Prevention

When it happens

Trigger: Calling FileUtil.getTotalLines(...) with a File that is a directory or does not exist.

Common situations: 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.

Related errors


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/8f3377e01aadb4f9. Report an issue: GitHub.