и первый комментарий Питера Ценга для обходного пути.

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

Я знаю, что определение «допустимого пути к файлу» варьируется в зависимости от операционной системы, но мне было интересно, есть ли какой-нибудь быстрый способ принять «C: / foo» или «/ foo» и отвергнуть «банан» ... возможный подход возможно, попытка создать файл и в конечном итоге удалить его, если создание прошло успешно, но я надеюсь, что есть более элегантный способ достижения того же результата ...

 boly3804 февр. 2016 г., 14:27
связанная документация по проверке от klocwork:SV.PATH : содержит полезные рекомендации
 david blaine18 дек. 2012 г., 03:57
Может кто-нибудь сказать мне, как вышеуказанный вопрос в точности связан с этим -stackoverflow.com/questions/13924808/... ? Хорошо, я могу дать 2 сходства - оба написаны на английском языке и используют слово «есть». Что-нибудь кроме этого?

Ответы на вопрос(6)

File.getCanonicalPath() довольно полезно для этой цели. Исключения ввода-вывода генерируются для определенных типов недопустимых имен файлов (например,CON, PRN, *?* в Windows) при разрешении относительно ОС или файловой системы. Однако это только предварительная проверка; вам все равно придется обрабатывать другие сбои при создании файла (например, недостаточные разрешения, нехватка места на диске, ограничения безопасности).

Ваше отсутствие необходимых разрешений;На устройстве недостаточно места;Устройство испытывает ошибку;Некоторая политика пользовательской безопасности запрещает вам создавать файлы определенного типа;и т.п.

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

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

Если это только часть какого-либо процесса диагностики или установки, просто сделайте это и посмотрите, работает ли он. Опять же, нет гарантии, что это сработает позже.

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

 jim22 янв. 2009 г., 13:38
Не делайте этого (в некоторых случаях), разрешите пользователю выбрать другой том или носитель. У меня есть IDE, которая умирает, когда не может записать файл своего проекта. Хорошо, том отключен - позвольте мне выбрать другое место и продолжить ,

введенный в Java 7, добавляет новые альтернативы, например:
(Делаетне правильно работать подLinux - всегда возвращает true)

/**
 * <pre>
 * Checks if a string is a valid path.
 * Null safe.
 *  
 * Calling examples:
 *    isValidPath("c:/test");      //returns true
 *    isValidPath("c:/te:t");      //returns false
 *    isValidPath("c:/te?t");      //returns false
 *    isValidPath("c/te*t");       //returns false
 *    isValidPath("good.txt");     //returns true
 *    isValidPath("not|good.txt"); //returns false
 *    isValidPath("not:good.txt"); //returns false
 * </pre>
 */
public static boolean isValidPath(String path) {
    try {
        Paths.get(path);
    } catch (InvalidPathException | NullPointerException ex) {
        return false;
    }
    return true;
}
 Groostav28 июн. 2016 г., 22:55
обратите внимание, что это всегда возвращаетtrue на Linux. В моем собственном тестировании дажеPaths.get("file\u0000") не бросаетInvalidPathException.
 c0der10 июн. 2016 г., 15:47
Спасибо @ Тим Визе. Я рад, что вы найдете это хорошее решение (0:
 Tim Visée09 июн. 2016 г., 21:47
Красивый! Хорошее и чистое решение без необходимости включать библиотеки Apache.
 c0der29 июн. 2016 г., 09:14
@ Groostav спасибо за важную заметку. Я не могу проверить это на Linux. Если проблема, которую вы подняли, будет подтверждена, я добавлю к ней примечание. Если у вас есть решение, пожалуйста, опубликуйте его.
 ArtOfWarfare18 мая 2018 г., 17:45
@nllsdfx - Не работает в Linux, что не так, если он возвращает истину для этого? Вполне допустимо иметь имя каталога с точками в нем, если вы думаете, что это неправильно ...
Решение Вопроса

Это также проверит наличие каталога.

File file = new File("c:\\cygwin\\cygwin.bat");
if (!file.isDirectory())
   file = file.getParentFile();
if (file.exists()){
    ...
}

Кажется, что file.canWrite () не дает вам четкого указания, если у вас есть права на запись в каталог.

 mtruesdell22 янв. 2009 г., 13:45
Код krosenvold выполняет следующие действия: существует ли переданное имя файла уже как каталог, и если нет, существует ли каталог, в котором он будет существовать? Это имеет смысл, поскольку, если каталог существует, вы можете создать файл (разрешения разрешают). Обратите внимание, что новый файл ("foo") не создает файл.
 tddmonkey22 янв. 2009 г., 12:48
Проблема в том, что возможность создания файла может измениться после того, как вы проверили, можно ли его создать
 Raibaz22 янв. 2009 г., 12:46
Хм ... я не хочу проверять, существует ли файл, я хочу проверить, можно ли создать файл в текущей файловой системе
 david blaine18 дек. 2012 г., 02:39
поместите это в конструктор File "c: [] [] cygwin \\ cygwin.bat" ... затем поместите операторы печати в оба ifs - "dir found" в 1-м if и "file found" во втором if. выходной файл - это dir found, что явно не то же самое, что проверка правильности / допустимости имени пути.
 mike22 июл. 2013 г., 14:37
Примечание. На самом деле вы не создаете файл в файловой системе сnew File("some/path"), Таким образом, вы можете использовать их в целях проверки. Для создания файлов в файловой системе необходимоcreateNewFile и т.п.
boolean canWrite(File file) {
  if (file.exists()) {
    return file.canWrite();
  }
  else {
    try {
      file.createNewFile();
      file.delete();
      return true;
    }
    catch (Exception e) {
      return false;
    }
  }
}
 sullivan-14 июл. 2011 г., 20:32
Это не полностью работает, так какFile.canWrite() не надежно на Windows. Видетьэта почта и первый комментарий Питера Ценга для обходного пути.

Вот что вы можете сделать, что работает в разных операционных системах

Использование соответствия регулярному выражению для проверки существующих известных недопустимых символов.

if (newName.matches(".*[/\n\r\t\0\f`?*\\<>|\":].*")) {
    System.out.println("Invalid!");
} else {
    System.out.println("Valid!");
}

Pros

Это работает через операционные системыВы можете настроить его так, как захотите, отредактировав это регулярное выражение.

Cons

Это может быть не полный список, и нужно больше исследований, чтобы заполнить больше недопустимых шаблонов или символов.

Ваш ответ на вопрос