Can FileInputStream.available stupid me?

ThisInputStream.available () javadoc file says:

Returns an estimate of the number of remaining bytes that can be read (or skipped) from this input stream without blocking the next method call for this input stream. The next call may be the same thread or another thread. one reading or skipping this number of bytes will not block, but can read or skip fewer bytes.

In some cases, non-blocking reading (or skipping) can be blocked when it is just slow, for example, when reading large files on slow networks.

I am not sure about this check:

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

Can we assume that empty files will always return zero?

-

Thanks to @SB, who didn’t exactly answer the question, but was the first to give a better alternative:

If xmlFile is a java.io.File object, you can use the length () method to get its size.

+4
source share
4 answers

You can rely on new FileInputStream(fileName).available() , returning zero if the named file is empty.

You cannot rely on new FileInputStream(fileName).available() == 0 as the final test that the file is empty. If fileName is a regular file on the local file system, it will probably work. But if fileName is a device file or if it is a file on a remote file system, available() can return zero to indicate that a read() will need to be blocked for a period. (Or, in the case of the remote file system, this may not be the case.)

A more reliable way to check the length of a regular file is to use new File(fileName).length() == 0 . However, for a device file or channel, a call to length() can return zero, regardless of the number of bytes that can ultimately be read. And keep in mind that new File(fileName).length() also returns zero if the file does not exist.

EDIT If you need a reliable test to find out if a file is empty, you need to make several calls:

 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(...); } } 

But it would be useful for you to thoroughly test this with various file types on all platforms on which you run your application. The behavior of some file predicates is documented as platform specific; see javadoc .

+2
source

I highly recommend using accessible () - it can return 0 because the stream is blocked, although there are still enough bytes to read. This will probably not happen with files, but the API does not guarantee that it will not.

The same approach can be used with read (), though:

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

If xmlFile is a java.io.File object, you can use the length () method to get its size.

+2
source

My logical answer to the question is "can I rely on empty files to always return zero?" "Yes, for empty files available() will return 0."

But you probably also want to know "can I rely on only empty files to return zero?", And there the answer is "No, not according to the specification: available() can return 0 even if the file is not empty."

In addition, you open the stream in a file and do not close it again. This can lead to unexpected and unwanted behavior, for example. you cannot move or delete the file while your Java program is running. This is especially annoying if your program runs on an application server that usually runs for a very long time, which makes the file efficient and unchanged.

+2
source

Source: https://habr.com/ru/post/1309121/


All Articles