Разница между File.separator и косой чертой в путях

В чем разница между использованием File.separator и нормальный / в строке пути Java?

В отличие от двойной обратной косой черты \\ Независимость от платформы, похоже, не является причиной, поскольку обе версии работают под Windows и Unix.

public class SlashTest {
    @Test
    public void slash() throws Exception {
        File file = new File("src/trials/SlashTest.java");
        assertThat(file.exists(), is(true));
    }

    @Test
    public void separator() throws Exception {
        File file = new File("src" + File.separator + "trials" + File.separator + "SlashTest.java");
        assertThat(file.exists(), is(true));
    }
}

Перефразировать вопрос, если / работает на Unix и Windows, почему нужно использовать File.separator?

14 ответов

Решение

С библиотеками Java для работы с файлами вы можете безопасно использовать / (косая черта, а не обратная косая черта) на всех платформах. Код библиотеки обрабатывает внутреннее преобразование вещей в специфичные для платформы пути.

Вы можете использовать File.separator в пользовательском интерфейсе, тем не менее, потому что лучше показать людям, что будет иметь смысл в их ОС, а не что имеет смысл для Java.

Обновление: я не смог за пять минут поиска найти документированное поведение "всегда можно использовать косую черту". Теперь, я уверен, что я видел это задокументированным, но в отсутствие нахождения официальной ссылки (потому что моя память не идеальна), я бы придерживался использования File.separator потому что ты знаешь, что это сработает.

Ты используешь File.separator потому что когда-нибудь ваша программа может работать на платформе, разработанной в далекой стране, стране странных вещей и незнакомых людей, где лошади плачут, а коровы управляют всеми лифтами. На этой земле люди традиционно использовали символ ":" в качестве разделителя файлов, и поэтому JVM покорно подчиняется их желаниям.

Хотя использование File.separator для ссылки на имя файла является излишним (для тех, кто представляет далёкие земли, я думаю, что их реализация JVM заменит / с : так же, как Windows, JVM заменяет его на \).

Однако иногда вы получаете ссылку на файл, а не создаете его, и вам необходимо проанализировать его, и для того, чтобы сделать это, вам нужно знать разделитель на платформе. File.separator поможет вам сделать это.

Хорошо, давайте проверим некоторый код.
File.java строки 428 до 435 в File.<init>:

String p = uri.getPath();
if (p.equals(""))
    throw new IllegalArgumentException("URI path component is empty");

// Okay, now initialize
p = fs.fromURIPath(p);
if (File.separatorChar != '/')
p = p.replace('/', File.separatorChar);

И давайте прочитаем fs/*(FileSystem)*/.fromURIPath() документы:

java.io.FileSystem
public abstract String fromURIPath (Строковый путь)
Постобработка указанной строки пути URI, если необходимо. Это используется в win32, например, для преобразования "/c:/foo" в "c:/foo". Строка пути все еще имеет разделители слэша; код в классе File переведет их после возврата этого метода.

Это означает FileSystem.fromURIPath() выполняет постобработку по пути URI только в Windows, а потому в следующей строке:

p = p.replace('/', File.separatorChar);

Он заменяет каждый '/' системно-зависимым seperatorChar, вы всегда можете быть уверены, что "/" безопасен в любой ОС.

Что ж, операционных систем больше, чем Unix и Windows (портативные устройства и т. Д.), А Java известна своей переносимостью. Лучше всего использовать его, чтобы JVM могла определить, какой из них лучше для этой ОС.

Поздно на вечеринку. Я на Windows 10 с JDK 1.8 и Eclipse MARS 1.
Я нахожу это

getClass().getClassLoader().getResourceAsStream("path/to/resource");

работает и

getClass().getClassLoader().getResourceAsStream("path"+File.separator+"to"+File.separator+"resource");

не работает и

getClass().getClassLoader().getResourceAsStream("path\to\resource");

не работает. Последние два эквивалентны. Итак... У меня есть веская причина НЕ использовать File.separator.

Хотя это не имеет большого значения на обратном пути, но на обратном пути.

Конечно, вы можете использовать '/' или '\' в новом файле (путь строки), но File.getPath() даст вам только один из них.

Портативность проста и понятна.

"Java SE8 для программистов" утверждает, что Java справится с любым из них. (стр. 480, последний абзац). В примере утверждается, что:

c:\Program Files\Java\jdk1.6.0_11\demo/jfc

разберусь просто отлично. Обратите внимание на последний разделитель (в стиле Unix).

Это липко и, вероятно, подвержено ошибкам, но это то, что они (Deitel и Deitel) утверждают.

Я думаю, что путаница для людей, а не Java, является достаточной причиной, чтобы не использовать эту (неправильную?) Функцию.

Как господа описали разницу с деталями варианта.

Я хотел бы рекомендовать использование Apache Commons io api, класс FilenameUtils при работе с файлами в программе возможно развертывание на нескольких ОС.

Использование File.separator заставило Ubuntu генерировать файлы с именем "\" вместо каталогов. Может быть, мне лень, как я делаю файлы (и каталоги), и я мог бы избежать этого, независимо от того, что каждый раз использую "/", чтобы избежать файлов с "\" в названии.

Если вы используете Java 7, извлеките Path.resolve() и Paths.get ().

Путь к файлу или каталогу указывается с использованием соглашений об именах хост-системы. Однако класс File определяет зависящие от платформы константы, которые можно использовать для обработки имен файлов и каталогов независимо от платформы.

Files.seperator определяет символ или строку, которые разделяют каталог и компоненты файла в имени пути. Этот разделитель - '/', '\' или ':' для Unix, Windows и Macintosh соответственно.

Что мне делать, если вы пытаетесь создать файл по какому-либо готовому пути (сохраненному в базе данных, например), используя разделитель Linux?

Может быть, просто используйте путь для создания файла:

new File("/shared/folder/file.jpg");

Но Windows использует другой разделитель (\). Итак, является ли альтернативой преобразование разделителя слеша в платформу независимым? Подобно:

new File(convertPathToPlatformIndependent("/shared/folder"));

Этот метод convertPathToPlatformIndependent вероятно, будет иметь какой-то вид разделения на "/" и соединится с File.separator.

Ну, для меня это нехорошо для языка, который не зависит от платформы (верно?), А Java уже поддерживает использование / в Windows или Linux. Но если вы работаете с путями и вам нужно помнить об этом преобразовании каждый раз, это будет кошмаром, и у вас не будет никакой реальной выгоды для приложения в будущем (возможно, во вселенной, описанной @Pointy).

Другие вопросы по тегам