1. long fileSize = file.length();
2. int fileSizeInt = fis.available();
3. long fileSize = fis.getChannel().size();

其中:

File file = File("文件路径");

FileInputStream fis = new FileInputStream(file);

测试一下这三种常用方式的效果:

package main.basic;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 测试读取大文件大小
 * @author lyg 20191231
 */
public class TestFileClass {
	private static final Logger log = LoggerFactory.getLogger(TestFileClass.class);

	public static void main(String[] args) throws IOException {
		File file = new File("我的测试文件本地路径");
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
			long fileSize = -1L;
			long startTime = -1L;
			long endTime = -1L;

			// 1.file.length
			log.info("1.file.length");
			startTime = System.nanoTime();
			fileSize = file.length();
			endTime = System.nanoTime();
			log.info("1.文件大小是:{}bit", fileSize);
			log.info("1.读取文件大小耗时:{}纳秒", endTime - startTime);

			// 2.fis.available();
			log.info("2.fis.available();");
			startTime = System.nanoTime();
			int fileSizeInt = fis.available();
			endTime = System.nanoTime();
			log.info("2.文件大小是:{}bit", fileSizeInt);
			log.info("2.读取文件大小耗时:{}纳秒", endTime - startTime);

			// 3.fis.getChannel().size();
			log.info("3.fis.getChannel().size();");
			startTime = System.nanoTime();
			fileSize = fis.getChannel().size();
			endTime = System.nanoTime();
			log.info("3.文件大小是:{}bit", fileSize);
			log.info("3.读取文件大小耗时:{}纳秒", endTime - startTime);
		} catch (FileNotFoundException e) {
			log.info("打开文件出现异常!");
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (Exception e) {
					log.info("关闭文件流失败!");
				}
			}
		}
	}
}

运行结果:

  • 测试文件大小为6KB左右的情况
16:29:25.382 [main] INFO main.basic.TestFileClass - 1.file.length
16:29:25.388 [main] INFO main.basic.TestFileClass - 1.文件大小是:69077bit
16:29:25.391 [main] INFO main.basic.TestFileClass - 1.读取文件大小耗时:119496纳秒

16:29:25.391 [main] INFO main.basic.TestFileClass - 2.fis.available();
16:29:25.391 [main] INFO main.basic.TestFileClass - 2.文件大小是:69077bit
16:29:25.391 [main] INFO main.basic.TestFileClass - 2.读取文件大小耗时:18327纳秒

16:29:25.391 [main] INFO main.basic.TestFileClass - 3.fis.getChannel().size();
16:29:25.397 [main] INFO main.basic.TestFileClass - 3.文件大小是:69077bit
16:29:25.397 [main] INFO main.basic.TestFileClass - 3.读取文件大小耗时:5592486纳秒
  •  测试文件大小为5GB左右的情况
16:11:52.072 [main] INFO main.basic.TestFileClass - 1.file.length
16:11:52.080 [main] INFO main.basic.TestFileClass - 1.文件大小是:5371154005bit
16:11:52.084 [main] INFO main.basic.TestFileClass - 1.读取文件大小耗时:167515纳秒

16:11:52.084 [main] INFO main.basic.TestFileClass - 2.fis.available();
16:11:52.084 [main] INFO main.basic.TestFileClass - 2.文件大小是:2147483647bit
16:11:52.084 [main] INFO main.basic.TestFileClass - 2.读取文件大小耗时:19427纳秒

16:11:52.084 [main] INFO main.basic.TestFileClass - 3.fis.getChannel().size();
16:11:52.090 [main] INFO main.basic.TestFileClass - 3.文件大小是:5371154005bit
16:11:52.090 [main] INFO main.basic.TestFileClass - 3.读取文件大小耗时:5723344纳秒

从结果上看,得出结论:

  1. 对于超过2G的大文件(准确来说是超过1.9xG),file.length();和fis.getChannel().size();两种读取方式可以正确获取文件大小,而fis.available();因为返回类型是Int型,超过2G就会溢出(准确来说是超过1.9xG),不再准确,因此大文件不推荐使用;
  2. 从速度上来说,若大文件不超限,file.length(); > fis.available(); > fis.getChannel().size();。考虑大文件超限,fis.available(); 被排除,那么file.length(); > fis.getChannel().size();
  3. 对于能获取File file 的情况下,优先考虑file.length();方式获取文件大小;对于一些网络传输的文件对象无法直接获取File file 的情况下,只能使用fis.getChannel().size();