Разница между 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).