2014-03-28 14:03 64507人阅读 评论(9) 收藏 举报
 分类:
Java笔记(36)  研究成果(42) 

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文出处:http://blog.csdn.net/chaijunkun/article/details/22387305,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。

今天写代码时需要实现获取文件大小的功能,目前有两种实现方法,一种是使用File的length()方法;另外一种是使用FileInputStream的available()方法,当InputStream未进行read操作时,available()的大小应该是等于文件大小的。但是在处理大文件时,后者会发生问题。我们来看一下:

在例子中,我使用了CentOS 6.5 的安装镜像文件,主要是考虑到这个文件足够大(大于2GB)。

1.使用File的length()方法

  1. public static void main(String[] args) {
  2. File f= new File("D:\\CentOS-6.5-x86_64-bin-DVD1.iso");
  3. if (f.exists() && f.isFile()){
  4. logger.info(f.length());
  5. }else{
  6. logger.info("file doesn't exist or is not a file");
  7. }
  8. }

我们看一下输出结果:

  1. 4467982336

结果是4.16GB,与Windows上显示的结果一致。

接下来我们看一下通过FileInputStream来获取的文件大小:

  1. public static void main(String[] args) {
  2. FileInputStream fis= null;
  3. try{
  4. File f= new File("D:\\CentOS-6.5-x86_64-bin-DVD1.iso");
  5. fis= new FileInputStream(f);
  6. logger.info(fis.available());
  7. }catch(Exception e){
  8. logger.error(e);
  9. } finally{
  10. if (null!=fis){
  11. try {
  12. fis.close();
  13. } catch (IOException e) {
  14. logger.error(e);
  15. }
  16. }
  17. }
  18. }

下面是运行结果:

  1. 2147483647

这个结果是不是很眼熟?它是Integer.MAX_VALUE,也就是有符号整型能表示的最大数值。

那么换算成熟悉的单位,这种方式获取的文件大小是多大呢?

约等于2GB,这显然不是正确的结果。

究其原因,File的length()方法返回的类型为long,long型能表示的正数最大值为:9223372036854775807,折算成最大能支持的文件大小为:8954730132868714 EB字节,这个量级将在人类IT发展史上受用很多很多年,而FileInputStream的avaliable()方法返回值是int,在之前也介绍了最大的表示范围,所能支持的最大文件大小为:1.99GB,而这个量级我们现在很容易就达到了。

2014年3月31日补充:

针对流式方法读取大文件大小也不是不可行,只是不能再使用传统的java.io.*下的包了,这里要用到java.nio.*下的新工具——FileChannel。下面我们来看下示例代码:

  1. public static void main(String[] args) {
  2. FileChannel fc= null;
  3. try {
  4. File f= new File("D:\\CentOS-6.5-x86_64-bin-DVD1.iso");
  5. if (f.exists() && f.isFile()){
  6. FileInputStream fis= new FileInputStream(f);
  7. fc= fis.getChannel();
  8. logger.info(fc.size());
  9. }else{
  10. logger.info("file doesn't exist or is not a file");
  11. }
  12. } catch (FileNotFoundException e) {
  13. logger.error(e);
  14. } catch (IOException e) {
  15. logger.error(e);
  16. } finally {
  17. if (null!=fc)){
  18. try{
  19. fc.close();
  20. }catch(IOException e){
  21. logger.error(e);
  22. }
  23. }
  24. }
  25. }

使用FileChannel后得到的结果与第一种情况吻合,准确地描述了文件的准确大小。

这里也同样提醒各位技术同仁,涉及到大文件读取的时候,对int类型的数据一定要留个心,以免出现隐藏的bug,定位起来很困难。

Java获取文件大小的正确方法(转)的更多相关文章

  1. Java中获取文件大小的正确方法

    本文出处:http://blog.csdn.net/djy1992/article/details/51146837,转载请注明.由于本人不定期会整理相关博文,会对相应内容作出完善.因此强烈建议在原始 ...

  2. java获取文件大小的方法

    目前Java获取文件大小的方法有两种: 1.通过file的length()方法获取: 2.通过流式方法获取: 通过流式方法又有两种,分别是旧的java.io.*中FileInputStream的ava ...

  3. Java获取各种常用时间方法大全

    Java获取各种常用时间方法大全 package cc.javaweb.test; Java中文网,Java获取各种时间大全 import java.text.DateFormat; import j ...

  4. java ----获取路径的各种方法(总结)

    Java Web开发中路径问题小结 (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 那么针对这个站点的几个基本概念表述如下: 1. web站点的根目录:http: ...

  5. Java 获取当前系统时间方法比较

    转载: http://blog.csdn.net/zzjjiandan/article/details/8372617 一. 获取当前系统时间和日期并格式化输出: import java.util.D ...

  6. java获取当前时间戳的方法

    获取当前时间戳 //方法 一 System.currentTimeMillis(); //方法 二 Calendar.getInstance().getTimeInMillis(); //方法 三 n ...

  7. java 获取路径的各种方法

    (1).request.getRealPath("/");//不推荐使用获取工程的根路径 (2).request.getRealPath(request.getRequestURI ...

  8. 【转载】java 获取路径的各种方法

    转载只供个人学习参考,查看请前往原出处:http://www.cnblogs.com/guoyuqiangf8/p/3506768.html 主要方法有: (1).request.getRealPat ...

  9. java获取文件大小

    1.使用File的length()方法获取.这个方法获取的字节数,由于返回的是Long类型所以能返回的最大值是Long.MAX_VALUE File file = new File( "D: ...

随机推荐

  1. codevs1099字串变换(Bfs)

    /* 最少步数问题 妥妥的Bfs 很显然队列里存的是串(可能存个数也可以 就像8数码那样) 然后每次队首元素弄出来 能换的都换一遍 最后每次换完的新串入队前先判断到头了没 最后说一句 String大法 ...

  2. Rational rose下载,安装,破解

    rationalrose是一个镜像文件,后缀名是bin 之前尝试过用虚拟光驱来打开,不知道为什么,在win10的环境下,虚拟光驱硬是不能加载bin文件,后来拷到虚拟机上,打开了bin镜像文件,得到了一 ...

  3. HTTPS双向认证

    生成证书 openssl genrsa -des3 -out server.key 2048 openssl req -new -x509 -key server.key -out ca.crt -d ...

  4. "SOAP WebService " 和 "RESTful WebService" 的定义分别是什么???

    一个个来,要知道区别,首先得知道各自的意义及用途web service采用Xml传输结构化的数据,轻量级跨平台而soap则是一种基于http的应用层通讯协议,同样采用xml编码,只不过soap又更进了 ...

  5. (转)echo和print的区别

    在实际使用中, print 和 echo 两者的功能几乎是完全一样.可以这么说,凡是有一个可以使用的地方,另一个也可以使用.但是,两者之间也还是一个非常重要的区别:在 echo 函数中,可以同时输出多 ...

  6. Android之fragment点击切换和滑动切换结合

    学了一小段时间的Android,主要接触的是UI设计,打交道最多莫过于fragment了吧.在Android3.0引入了fragment的概念后,几乎在所以的Android的应用中都可以看见其身影,已 ...

  7. sql 列轉行、行轉列

    PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P ...

  8. java_annotation_01

    一,Annotation简介 J2SE5.0提供了很多新的我,其中一个很重要的我就是对元数据的支持,在J2SE5.0中,这种元数据被称为注释,通过使用注释,程序开发人员可以在不改变原有逻辑的情况下,在 ...

  9. 对于HttpContext.Current的一点理解

    string[] userInfomationSplits = HttpContext.Current.User.Identity.Name.Split(new string[] { "\\ ...

  10. (转载)小课堂UI-Star Diamond Tutorial