Konwertuj adres URL do zwykłej nazwy pliku Windows Java

Czy jest sposób, aby to przekonwertować:

/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/myJar.jar
W to?:
C:\Users\David\Dropbox\My Programs\Java\Test\bin\myJar.jar

Używam poniższego kodu, który zwróci pełną ścieżkę .Archiwum JAR lub katalogu / bin.

fullPath = new String(MainInterface.class.getProtectionDomain()
            .getCodeSource().getLocation().getPath());

Problem polega na tym, że getLocation() zwraca URL i potrzebuję normalnej nazwy pliku windows. Próbowałem dodać po getLocation():

toString() and toExternalForm() both return:

file:/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/

getPath() zwraca:

/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/

Zwróć uwagę na %20, które należy przekształcić na miejsce.

Czy jest na to szybki i łatwy sposób?

Author: Andrey Adamovich, 2011-05-29

6 answers

Obecne zalecenie (z JDK 1.7+) to konwersja URL → URI → ścieżka. Aby przekonwertować adres URL na plik, można powiedzieć Paths.get(url.toURI()).toFile(). Jeśli nie możesz jeszcze korzystać z JDK 1.7, polecam new File(URI.getSchemeSpecificPart()).

Konwertowanie pliku → URI: najpierw pokażę Ci kilka przykładów, jakie Uri możesz uzyskać w Javie.

                          -classpath URLClassLoader File.toURI()                Path.toUri()
C:\Program Files          file:/C:/Program%20Files/ file:/C:/Program%20Files/   file:///C:/Program%20Files/
C:\main.c++               file:/C:/main.c++         file:/C:/main.c++           file:///C:/main.c++
\\VBOXSVR\Downloads       file://VBOXSVR/Downloads/ file:////VBOXSVR/Downloads/ file://VBOXSVR/Downloads/
C:\Résume.txt             file:/C:/R%c3%a9sume.txt  file:/C:/Résume.txt         file:///C:/Résume.txt
\\?\C:\Windows (non-path) file://%3f/C:/Windows/    file:////%3F/C:/Windows/    InvalidPathException

Kilka uwag na temat tych Uri:

    Specyfikacja URI to RFC 1738: URL , zastąpiony przez RFC 2396: URI, zastąpiony przez RFC 3986: URI . (WHATWG ma również specyfikację URI , ale nie określa, jak należy interpretować Uri plików.) Wszelkie zastrzeżone znaki w ścieżce są cytowane procentowo, a znaki inne niż ascii w URI są cytowane procentowo, gdy wywołujesz URI.toascistring().
  • plik.toURI () jest gorsza od Path.toUri () ponieważ plik.toURI () zwraca nietypowy Uri spoza RFC 1738 (podaje file: / zamiast file:///) i nie formatuje URI dla ścieżek UNC zgodnie z Microsoftu preferowany format . Żaden z tych URI UNC nie działa w Firefoksie (Firefox wymaga pliku://///).
  • ścieżka jest bardziej rygorystyczna niż plik; nie można skonstruować nieprawidłowej ścieżki z "\.\ "prefix . "Prefiksy te nie są używane jako część samej ścieżki", ale można je przekazać do API Win32.

Konwersja URI → plik: spróbujmy przekonwertować poprzednie przykłady na pliki:

                            new File(URI)            Paths.get(URI)           new File(URI.getSchemeSpecificPart())
file:///C:/Program%20Files  C:\Program Files         C:\Program Files         C:\Program Files
file:/C:/Program%20Files    C:\Program Files         C:\Program Files         C:\Program Files
file:///C:/main.c++         C:\main.c++              C:\main.c++              C:\main.c++
file://VBOXSVR/Downloads/   IllegalArgumentException \\VBOXSVR\Downloads\     \\VBOXSVR\Downloads
file:////VBOXSVR/Downloads/ \\VBOXSVR\Downloads      \\VBOXSVR\Downloads\     \\VBOXSVR\Downloads
file://///VBOXSVR/Downloads \\VBOXSVR\Downloads      \\VBOXSVR\Downloads\     \\VBOXSVR\Downloads
file://%3f/C:/Windows/      IllegalArgumentException IllegalArgumentException \\?\C:\Windows
file:////%3F/C:/Windows/    \\?\C:\Windows           InvalidPathException     \\?\C:\Windows

Ponownie, użycie Paths.get(URI) jest preferowane niż new File(URI), ponieważ Path jest w stanie obsłużyć UNC URI i odrzucić nieprawidłowe ścieżki z \?\ prefix. Ale jeśli nie możesz używać Javy 1.7, powiedz zamiast tego new File(URI.getSchemeSpecificPart()).

Przy okazji, do nie użyj URLDecoder do dekodowania adresu URL pliku. Dla plików zawierających "+", takich jak " file:///C: / main.c++", URLDecoder zamieni go w "C:\main.c"! URLDecoder służy tylko do analizowania zgłoszeń formularzy HTML application / x-www-form-urlencoded w zapytaniu URI (param=value&param=value), a nie do anulowania cytowania ścieżki URI.

2014-09: edytowano, aby dodać przykłady.

 69
Author: yonran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 07:52:09
String path = "/c:/foo%20bar/baz.jpg";
path = URLDecoder.decode(path, "utf-8");
path = new File(path).getPath();
System.out.println(path); // prints: c:\foo bar\baz.jpg
 17
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-28 21:44:07

Jak wspomniano-getLocation () zwraca adres URL. Plik może łatwo przekonwertować URI na ścieżkę, więc dla mnie najprostszym sposobem jest użycie:

File fullPath = new File(MainInterface.class.getProtectionDomain().
    getCodeSource().getLocation().toURI());

Oczywiście jeśli naprawdę potrzebujesz String, po prostu zmodyfikuj na:

String fullPath = new File(MainInterface.class.getProtectionDomain().
    getCodeSource().getLocation().toURI()).toString();

W ogóle nie potrzebujesz Urldecodera.

 3
Author: Mi-La,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-17 15:13:55

Poniższy kod jest tym, czego potrzebujesz:

String path = URLDecoder.decode("/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/", "UTF-8");
System.out.println(new File(path).getPath());
 2
Author: Andrey Adamovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-28 21:58:40

Obecne odpowiedzi wydają mi się podejrzane.

java.net.URL.getFile

Zamienia adres URL pliku taki jak ten

java.net.URL = file:/C:/some/resource.txt

Do tego

java.lang.String = /C:/some/resource.txt

Więc możesz użyć tego konstruktora

new File(url.getFile)

Aby podać ścieżkę Windows

java.io.File = C:\some\resource.txt
 2
Author: Pete Montgomery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-03 10:19:07

Witam zdezorientowanych ludzi z przyszłości. Jest tu niuans w konfiguracji ścieżki do pliku. Ścieżka, którą ustawiasz dla TESSDATA_PREFIX jest używana wewnętrznie przez program C++ tesseract, nie przez owijarkę Javy. Oznacza to, że jeśli używasz systemu windows, będziesz musiał zastąpić ukośnik wiodący i zastąpić wszystkie inne ukośniki do przodu z ukośnikami wstecznymi. Bardzo hacky workaround wygląda tak:

URL pathUrl = this.getClass().getResource(TESS_DATA_PATH);
String pathStr = pathUrl.getPath();

// hack to get around windows using \ instead of /
if (SystemUtils.IS_OS_WINDOWS) {
  pathStr = pathStr.substring(1);
  pathStr = pathStr.replaceAll("/", "\\\\");
}
 2
Author: xtro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-06 23:24:20