这个FileInputStream.available()javadoc说:
返回数量的估计值 可以读取的剩余字节数(或 从此输入流中跳过) 没有被下一个阻挡 调用此输入的方法 流。下一次调用可能是 相同的线程或另一个线程。一个 单个读取或跳过这么多字节 不会阻止,但可能会读取或跳过 更少的字节。
在某些情况下,非阻塞读取(或 skip)可能看起来被阻止了 只是缓慢,例如当 慢速读取大文件 网络
我不确定是否在此检查中:
if (new FileInputStream(xmlFile).available() == 0)
我可以依赖空文件总是返回零吗?
-
感谢@SB,他没有完全回答这个问题,但却是第一个提供最佳选择的人:
如果xmlFile是java.io.File对象, 你可以使用length()方法来获取 它的大小。
答案 0 :(得分:3)
如果指定的文件为空,可以依赖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。
答案 1 :(得分:2)
我强烈反对使用available() - 它可以返回0,因为流被阻止,即使仍有足够的字节要读取。它可能不会发生在文件中,但API不保证它不会。
同样的方法可以和read()一起使用:
if (new FileInputStream(xmlFile).read() == -1)
System.out.println("!!File empty!!");
答案 2 :(得分:2)
如果xmlFile是java.io.File对象,则可以使用length()方法来获取其大小。
答案 3 :(得分:2)
我对问题的合理回答“我可以依赖空文件总是返回零吗?”是“是的,对于空文件,available()
将返回0”。
但你可能也想知道“我可以依赖只有空文件会返回零吗?”,答案是“不,不是按照规范:available()
可能即使文件不为空,也返回0“。
此外,您正在打开文件流,不要再关闭它。这可能导致意外和不希望的行为,例如只要Java程序正在运行,您就可能无法移动或删除该文件。如果您的程序在通常运行很长时间的应用程序服务器中运行,这使得文件有效地不可变,这尤其令人讨厌。