Мне было интересно, как я могу проверить, равны ли файловые системы двух разных путей. Кажется неправильным писать что-то вроде
path1.fileSystem == path2.fileSystem
потому что может быть случай, когда файловые системы одинаковы по смыслу (они полностью идентичны), но на самом деле являются разными экземплярами и из-за этого path1.fileSystem == path2.fileSystem
может вернуться false
тогда, когда на самом деле должно вернуться true
. Тогда как мне сравнить файловые системы двух разных путей? Или ==
на самом деле в порядке и работает правильно в этой ситуации?
Я на самом деле пытался задать вопрос
boolean sameFileSystem = FileSystems.getDefault().provider().getScheme().equals(path1.getFileSystem().provider().getScheme())
&& FileSystems.getDefault().provider().getScheme().equals(path2.getFileSystem().provider().getScheme());
Обновление: мне нужно проверить это, чтобы сопоставить один путь с другим. (если файловые системы не одинаковы, я просто сделаю что-нибудь еще, эта часть не имеет значения? Мне просто нужно проверить, совпадают ли они)
Какой язык вы используете для выполнения этого конкретного теста. Java или Котлин?
Что именно вы хотите семантически узнать с помощью этой проверки. Зачем вам знать, то же ли это FileSystem
? Что же лежит в основе этого различия?
Вам нужна та же файловая система или, скорее, тот же поставщик? Ваше обновление не помогает понять вашу проблему. Почему вам нужно использовать другой путь, если файловые системы разные?
@Holger под «использовать другой путь» я имел в виду, что просто сделаю что-нибудь еще, это не очень важно, мне просто нужно проверить, одинаковы ли две файловые системы, чтобы я мог сопоставить один путь с другим
«чтобы я мог сопоставить один путь с другим» — вы можете сопоставить один путь с другим, если они оба принадлежат одному и тому же поставщику файловой системы; им не обязательно принадлежать к одной и той же файловой системе. И даже если они не принадлежат одному и тому же провайдеру, простое преобразование второго пути в строку и вызов resolve(String)
вместо resolve(Path)
подойдет в 99% всех случаев. Если вы действительно хотите сделать А, но в некоторых случаях прибегаете к Б, важно знать, что такое Б, поскольку это помогает понять, почему вы не переходите к А, несмотря на то, что А — это то, чего вы на самом деле хотите.
@Хольгер, это действительно ответ на мой вопрос, большое спасибо!
Если вы хотите знать, можете ли вы безопасно вызвать .resolve(Path) для двух существующих экземпляров Path
, вы должны проверить, принадлежат ли эти два пути одному и тому же провайдеру, а не файловой системе.
Провайдеров можно сравнивать с помощью оператора ==
; они должны быть одиночками.
Для сравнения, вот как Files.copy(…) проверяет, принадлежат ли два пути одному и тому же поставщику файловой системы:
public static Path copy(Path source, Path target, CopyOption... options) throws IOException { FileSystemProvider provider = provider(source); if (provider(target) == provider) { // same provider provider.copy(source, target, options); } else { // different providers CopyMoveHelper.copyToForeignTarget(source, target, options); } return target; }
…
private static FileSystemProvider provider(Path path) { return path.getFileSystem().provider(); }
В большинстве случаев запасной вариант с использованием .resolve(String)
работает, когда вам нужно разрешить пути разных поставщиков файловых систем:
static Path resolveWithForeignSupport(Path base, Path other) {
FileSystem fs1 = base.getFileSystem(), fs2 = other.getFileSystem();
if (fs1.provider() == fs2.provider()) {
return base.resolve(other);
}
if (other.getNameCount() <= 1 || fs1.getSeparator().equals(fs2.getSeparator())){
return base.resolve(other.toString());
}
Path resolved = base, othersRoot = other.getRoot();
if (othersRoot != null) {
resolved = resolved.resolve(othersRoot.toString());
}
for(Path component: other) {
resolved = resolved.resolve(component.toString());
}
return resolved;
}
Вы действительно наблюдали случай, когда
path1.fileSystem == path2.fileSystem
возвращалсяfalse
для той же файловой системы, или вы просто догадываетесь, что это может произойти? Обратите внимание:==
в Котлине не проверяет, является ли экземпляр точно таким же, но использует методequals
. Я не совсем уверен, сможем ли мы проверить файловые системы на равенство, и в документации это неясно. Но я хочу сказать: возможно, это работает именно так, как вы ожидаете.