zoukankan      html  css  js  c++  java
  • 获取文件大小

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

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

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

    1.使用File的length()方法

    [java] view plain copy
     
    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. }  

    我们看一下输出结果:

    [plain] view plain copy
     
    1. 4467982336  


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

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

    [java] view plain copy
     
    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. }  

    下面是运行结果:

    [plain] view plain copy
     
    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。下面我们来看下示例代码:

    [java] view plain copy
     
    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,定位起来很困难。

  • 相关阅读:
    mybatis 错误 Invalid bound statement (not found)
    Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
    bug 记录 Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans
    解决:The Tomcat connector configured to listen on port 8182 failed to start. The port may already be in use or the connector may be misconfigured.
    jquery validate 验证插件 解决多个相同的Name 只验证第一个的方案
    phpStorm+xdebug调试(php7.3)
    小程序视频多个视频播放与暂停
    CSS实现单行、多行文本溢出显示省略号(…)
    Packet for query is too large (4,544,730 > 4,194,304). You can change this value on the server by setting the 'max_allowed_packet' variable.
    idea自动在文件头中添加作者和创建时间
  • 原文地址:https://www.cnblogs.com/zxwBj/p/8597994.html
Copyright © 2011-2022 走看看