Может ли FileInputStream.available обмануть меня? - PullRequest
6 голосов
/ 07 мая 2010

Этот javadoc FileInputStream.available () говорит:

Возвращает оценку количества остальные байты, которые можно прочитать (или пропущено) из этого входного потока без блокировки на следующий вызов метода для этого ввода поток. Следующий вызов может быть та же самая нить или другая нить. одно чтение или пропуск этого количества байтов не будет блокировать, но может читать или пропускать меньше байтов.

В некоторых случаях неблокирующее чтение (или пропустить) может оказаться заблокированным, когда он просто медленно, например, когда чтение больших файлов через медленный сетей.

Я не уверен, что в этом чеке:

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

Могу ли я рассчитывать, что пустые файлы всегда будут возвращать ноль?

-

Спасибо @SB, который точно не ответил на вопрос, но первым дал лучшую альтернативу:

Если xmlFile является объектом java.io.File, Вы можете использовать метод length (), чтобы получить его размер.

Ответы [ 4 ]

3 голосов
/ 07 мая 2010

Вы можете полагаться на 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 .

2 голосов
/ 07 мая 2010

Если xmlFile является объектом java.io.File, вы можете использовать метод length () , чтобы получить его размер.

2 голосов
/ 07 мая 2010

Мой логический ответ на вопрос «Могу ли я рассчитывать, что пустые файлы всегда будут возвращать ноль?» - это «Да, для пустых файлов available() вернет 0».

Но вы, вероятно, также хотите знать, «могу ли я рассчитывать, что только пустые файлы вернет ноль?», И там ответ «Нет, не по спецификации: available() может вернуть даже 0 если файл не пустой ".

Кроме того, вы открываете поток для файла и не закрываете его снова. Это может привести к неожиданному и нежелательному поведению, например, вы не сможете перемещать или удалять файл, пока работает ваша Java-программа. Это особенно раздражает, если ваша программа запускается на сервере приложений, который обычно выполняется очень долго, что делает файл практически неизменным.

2 голосов
/ 07 мая 2010

Я настоятельно рекомендую не использовать available () - он может возвращать 0, потому что поток заблокирован, хотя для чтения еще достаточно байтов. Это, вероятно, не произойдет с файлами, но API не гарантирует, что это не произойдет.

Тот же подход можно использовать с read (), хотя:

if (new FileInputStream(xmlFile).read() == -1)  
  System.out.println("!!File empty!!");  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...