【问题标题】:May the FileInputStream.available foolish me?FileInputStream.available 可能会愚弄我吗?
【发布时间】:2010-05-07 13:29:03
【问题描述】:

这个 FileInputStream.available() javadoc 说:

返回估计的数量 可以读取的剩余字节数(或 跳过)从此输入流 没有被下一个阻塞 为此输入调用方法 溪流。下一次调用可能是 同一个线程或另一个线程。一种 单次读取或跳过这么多字节 不会阻塞,但可以读取或跳过 更少的字节数。

在某些情况下,非阻塞读取(或 跳过)可能会出现被阻止时 只是很慢,例如当 读取大文件速度慢 网络。

我不确定是否在此检查中:

if (new FileInputStream(xmlFile).available() == 0)

我可以相信空文件总是返回零吗?

--

感谢@SB,他并没有完全回答这个问题,而是第一个给出了最佳选择:

如果 xmlFile 是 java.io.File 对象, 您可以使用 length() 方法获取 它的大小。

【问题讨论】:

    标签: java file-io


    【解决方案1】:

    如果命名文件为空,您可以依靠new FileInputStream(fileName).available() 返回零。

    不能依赖new FileInputStream(fileName).available() == 0 作为文件为空的明确测试。如果fileName 是本地文件系统上的常规文件,它可能会起作用。但是如果fileName 是一个设备文件或者它是一个远程文件系统上的文件,available() 可能会返回零来报告read() 将不得不阻塞一段时间。 (或者在远程文件系统的情况下,它可能不会。)

    测试常规文件长度的更可靠方法是使用new File(fileName).length() == 0。但是对于设备文件或管道,length() 调用可能会返回零,而与最终可以读取的字节数无关。请记住,如果文件不存在,new File(fileName).length() 也会返回零。

    编辑如果您想要一个可靠的测试来查看文件是否为空,您必须进行多次调用:

    public static isEmptyFile(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            return false;
        } else if (file.length() != 0L) {
            return false;
        } else if (file.isFile()) {
            return true;
        } else if (file.isDirectory()) {
            return false;
        } else {
            // It may be impossible to tell that a device file / named pipe is
            // "empty" without actually reading it.  This is not a failing of
            // Java: it is a logical consequence of the way that certain
            // devices, etc work.
            throw new CannotAnswerException(...);
        }
    }        
    

    但建议您在运行应用程序的所有平台上使用各种“文件”类型仔细测试。一些文件谓词的行为被记录为特定于平台;见javadoc

    【讨论】:

    • 所以我要么不能依赖length()?没有可靠的测试?
    【解决方案2】:

    我强烈建议不要使用 available() - 它可以返回 0,因为流被阻塞,即使仍有足够的字节要读取。文件可能不会发生这种情况,但 API 不保证不会发生。

    同样的方法也可以用于 read():

    if (new FileInputStream(xmlFile).read() == -1)  
      System.out.println("!!File empty!!");  
    

    【讨论】:

      【解决方案3】:

      如果 xmlFile 是 java.io.File 对象,则可以使用length() 方法获取其大小。

      【讨论】:

      • @SB - 但是,File.length() 在非零长度文件的情况下返回零;请参阅 javadoc。
      • Stephen - 好点,但我认为它比使用 available 更好。如果文件是目录或不存在,available 会做什么?我的猜测是它返回 0,但如果大小 > 0,它也可以返回 0。
      【解决方案4】:

      我对 “我可以相信空文件将始终返回零吗?”问题的逻辑回答是“是的,对于空文件,available() 将返回 0”。

      但您可能还想知道“我可以相信只有空文件会返回零吗?”,答案是“不,不是按照规范:available() 可能返回 0即使文件不为空”。

      此外,您正在打开文件上的流并且不要再次关闭它。这可能会导致意外和不受欢迎的行为,例如只要您的 Java 程序正在运行,您就可能无法移动或删除该文件。如果您的程序在通常运行很长时间的应用程序服务器中运行,则这尤其令人讨厌,从而使文件实际上是不可变的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-15
        • 2014-01-22
        • 2014-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多