Подтвердить что ты не робот

Как дорого стоит File.exists в Java

Мне интересно, как работает File.exists(). Я не очень хорошо знаю, как работают файловые системы, поэтому я должен сначала начать чтение.

Но для быстрой предварительной информации:

Является ли вызов File.exists() единственным действием для файловой системы, если этот путь и имя файла зарегистрированы в каком-то журнале? Или ОС получает содержимое каталога, а затем просматривает его для совпадений?

Я предполагаю, что это будет зависящим от файловой системы, но, возможно, все файловые системы используют быстрый подход?

Я не говорю о сетевых и ленточных системах. Давайте сохраним его в ntfs, extX, zfs, jfs: -)

4b9b3361

Ответ 1

Как эта операция, если выполняется в первый раз, полностью зависит от файловой системы. Это делается ОС, и Java не играет никакой роли.

В плане производительности во всех случаях требуется чтение на диск. Обычно это занимает 8-12 мс. @Sven указывает, что некоторое хранилище может замедляться, но это относительно редко в тех случаях, когда производительность важна. У вас может быть дополнительная задержка, если это сетевая файловая система (обычно относительно небольшая, но зависит от вашей сетевой задержки).

Все остальное, что делает ОС и Java, очень мало по сравнению.

Однако, если вы проверяете, что файл существует несколько раз, доступ к диску может не потребоваться, поскольку информация может кэшироваться, в этом случае время, которое занимает ОС, и ресурсы. Один из самых больших из них создает объекты File.exists() (вы бы не подумали, что это так), однако он кодирует имя файла при каждом вызове, создавая много объектов. Если вы помещаете File.exists() в замкнутый цикл, он может создавать 400 Мбайт мусора в секунду.: (

Журналы файловых систем работают по-разному, отслеживая все изменения, внесенные вами в файловую систему, однако они не меняют способ чтения файловой системы.

Ответ 2

Измерьте необходимое время и убедитесь сами. Как вы говорите, он зависит от файловой системы.

        long t1 = System.currentTimeMillis();
        ...Your File.exists call
        long t2 = System.currentTimeMillis();
        System.out.println("time: " + (t2 - t1) + " ms");

Вы увидите, что он всегда даст вам разные результаты, так как это зависит также от того, как ваша ОС кэширует данные, их загрузку и т.д.

Ответ 3

Большинство операций с файлами не выполняются в Java; для выполнения этих действий существует собственный код. В действительности большая часть выполняемой работы зависит от характера объекта FileSystem (который поддерживает объект File) и базовой реализации собственных операций ввода-вывода в ОС.

Я продемонстрирую случай реализации в OpenJDK 6, для ясности. Реализация File.exists() отменяет фактические проверки в классе FileSystem:

public boolean exists() {
    ... calls to SecurityManager have been omitted for brevity ...
    return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
}

Класс FileSystem является абстрактным, и существует реализация для всех поддерживаемых файловых систем:

package java.io;


/**
 * Package-private abstract class for the local filesystem abstraction.
 */

abstract class FileSystem

Обратите внимание на частную природу пакета. Java Runtime Environment предоставит конкретные классы, расширяющие класс FileSystem. В реализации OpenJDK есть:

  • java.io.WinNTFileSystem, для NTFS
  • java.io.Win32FileSystem, для FAT32
  • java.io.UnixFileSystem для файловых систем * nix (это класс с очень большой ответственностью).

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

Обновление # 2

Исходя из обновленного вопроса -

Я не говорю о сетевых и ленточных системах. Давайте сохраним его в ntfs, extX, zfs, jfs

Ну, это все равно не имеет значения. Различные операционные системы будут осуществлять поддержку различных файловых систем по-разному. Например, поддержка NTFS в Windows будет отличаться от той, что указана в * nix, так как операционная система также должна будет делать это как часть бухгалтерского учета, в дополнение к общению с устройствами через своих драйверов; не все работы выполняются на устройстве.

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

В * nix вы получите системный вызов stat(), который будет выполнять необходимую работу по чтению информации об идентификаторе дескриптора файла.