2014-01-11 2 views
31

Я пытаюсь понять, как Java разрешает относительный путь при создании объекта File.Как Java разрешает относительный путь в новом файле()?

OS используется: Windows

Для ниже фрагмента кода, я получаю IOException, поскольку он не может найти путь:

@Test 
public void testPathConversion() { 
     File f = new File("test/test.txt"); 
     try { 
      f.createNewFile(); 
      System.out.println(f.getPath()); 
      System.out.println(f.getAbsolutePath());  
      System.out.println(f.getCanonicalPath()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
} 

Моего понимание здесь есть, Java рассматривает пути при условии абсолютных и возвратов ошибка, когда путь не существует. Так что это имеет смысл.

Когда я обновляю код выше, чтобы использовать относительный путь:

@Test 
    public void testPathConversion() { 
     File f = new File("test/../test.txt"); 
     try { 
      f.createNewFile(); 
      System.out.println(f.getPath()); 
      System.out.println(f.getAbsolutePath());  
      System.out.println(f.getCanonicalPath()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     }  
    } 

Он создает новый файл и обеспечивает ниже вывод:

test\..\test.txt 
C:\JavaForTesters\test\..\test.txt 
C:\JavaForTesters\test.txt 

В этом случае, мое предположение, несмотря на то, предоставленный путь не существует, поскольку путь содержит «/../», java рассматривает это как относительный путь и создает файл в user.dir. Так что это также имеет смысл.

Но если я обновлю относительный путь, как показано ниже:

@Test 
    public void testPathConversion() { 
     File f = new File("test/../../test.txt"); 
     try { 
      f.createNewFile(); 
      System.out.println(f.getPath()); 
      System.out.println(f.getAbsolutePath()); 
      System.out.println(f.getCanonicalPath()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

Тогда я получаю IOException: доступ запрещен.

Мои вопросы:

  1. почему "test/../test.txt" рассматривается как относительный путь и создает файл в "user.dir" но "test/../../test.txt" возвращает ошибку? Где он пытается создать файл для пути "test/../../test.txt"?
  2. Если указанный относительный путь не найден, файл создается в user.dir. Таким образом, мне кажется, что приведенные ниже два сценария делает то же самое:

    //scenario 1 
    File f = new File("test/../test.txt"); 
    f.createNewFile(); 
    
    //scenario 2 
    File f = new File("test.txt"); 
    f.createNewFile(); 
    

Так есть реальный мир случай, когда можно было бы использовать сценарий 1 вместо сценария 2?

Я полагаю, что мне не хватает чего-то очевидного здесь или в корне неправильно понятых относительных путей. Я просмотрел документы Java для файла, и я не могу найти объяснения этого. В Stack Overflow имеется довольно много вопросов относительно относительных путей, но те, которые я искал, касались конкретных сценариев, а не точно, как разрешены относительные пути.

Будет здорово, если кто-то может объяснить мне, как это работает или указывать на некоторые связанные ссылки?

+0

Обратите внимание, что 'user.dir' является довольно изменчивым местом, которое было бы хрупким для приложения, на которое можно положиться. Еще один фактор, который следует учитывать, - это приложение.не может быть установлен в месте, где у него есть права на запись. ** Было бы более оптимальным и надежным сделать файл в (подкаталог) 'user.home'. См. [Этот ответ] (http://stackoverflow.com/a/10166623/418556) для краткого примера. –

+0

Примечание: 'test/test.txt' и' test /../ test.txt' - оба относительных пути. Относительно этого значения не имеет ничего общего с наличием встроенных компонентов '..'. – Boann

ответ

17

Существует концепция working directory.
Этот каталог представлен . (точка).
В относительных дорогах все остальное относительно этого.

Просто введите . (рабочий каталог), где вы запускаете свою программу.
В некоторых случаях рабочий каталог можно изменить, но в целом это
что представляет точка. Я думаю, что это C:\JavaForTesters\ в вашем случае.

Так test\..\test.txt означает: подкаталог test
в моем рабочем каталоге, то один уровень вверх, то
файл test.txt. Это в основном то же самое, что и test.txt.

Для получения дополнительной информации проверьте здесь.

http://docs.oracle.com/javase/7/docs/api/java/io/File.html

http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html

5

Рабочий каталог является общей концепции по практически все операционные системы и языки программирования и т.д. Это каталог, в котором ваша программа работает. Обычно это (но не всегда, есть способы изменить его) в каталоге, в котором находится приложение.

Относительные пути - это те, которые начинаются без указателя диска. Так что в linux они не начинаются с /, в окнах они не начинаются с C:\ и т. Д. Они всегда начинаются с вашего рабочего каталога.

Абсолютные пути - это те, которые начинаются с указателя привода (или машины для сетевых путей). Они всегда идут с самого начала этого диска.

7

Когда ваш путь начинается с корня dir i.e C:\ в Windows или / в Unix или в пути ресурсов java, он считается абсолютным путем. Все остальное является относительным, так

new File("test.txt") is the same as new File("./test.txt") 

new File("test/../test.txt") is the same as new File("./test/../test.txt") 

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

Примечание: File.equals использует абстрактную форму пути (getAbsolutePath) для сравнения файлов, так что это означает, что два File объекты для того же не могут быть равны и File s являются небезопасными для использования в коллекциях как Map или Set.

0

На окнах и Netbeans вы можете установить относительный путь, как:

new FileReader("src\\PACKAGE_NAME\\FILENAME"); 

В Linux и Netbeans вы можете установить относительный путь, как:

new FileReader("src/PACKAGE_NAME/FILENAME"); 

Если у вас есть код внутри Source Packages Я не знаю, является ли это одинаковым для затмения или другой IDE

0

Только слегка связано с вопросом, но попробуйте обернуть голову arou и этот. Таким образом, неинтуитивно понятный:

import java.nio.file.*; 
class Main { 
    public static void main(String[] args) { 
    Path p1 = Paths.get("/personal/./photos/./readme.txt"); 
    Path p2 = Paths.get("/personal/index.html"); 
    Path p3 = p1.relativize(p2); 
    System.out.println(p3); //prints ../../../../index.html !! 
    } 
} 
Смежные вопросы