Vraag Converteer URL naar normale windows bestandsnaam Java


Is er een manier om dit te converteren:

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

in dit?:

C:\Users\David\Dropbox\My Programs\Java\Test\bin\myJar.jar

Ik gebruik de volgende code, die het volledige pad van het .JAR-archief of de / bin-directory zal retourneren.

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

Het probleem is, getLocation() geeft a terug URL en ik heb een normale Windows-bestandsnaam nodig. Ik heb geprobeerd het volgende toe te voegen getLocation():

toString() en toExternalForm() beide keren terug:

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

getPath() komt terug:

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

Merk op %20 die moet worden omgezet in ruimte.

Is er een snelle en eenvoudige manier om dit te doen?


49
2018-05-28 21:30


oorsprong


antwoorden:


De huidige aanbeveling (met JDK 1.7+) is om URL → URI → Pad te converteren. Dus om een ​​URL naar Bestand te converteren, zou je zeggen Paths.get(url.toURI()).toFile(). Als u JDK 1.7 nog niet kunt gebruiken, zou ik aanraden new File(URI.getSchemeSpecificPart()).

Bestanden converteren → URI: Eerst zal ik u enkele voorbeelden laten zien van welke URI's u waarschijnlijk in Java zult krijgen.

                          -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

Enkele opmerkingen over deze URI's:

  • De URI-specificaties zijn RFC 1738: URL, vervangen door RFC 2396: URI, vervangen door RFC 3986: URI. (De WHATWG heeft ook een URI spec, maar het geeft niet aan hoe bestands-URI's moeten worden geïnterpreteerd.) Alle gereserveerde tekens binnen het pad zijn procentueel geciteerd en niet-ascii-tekens in een URI worden procentueel genoteerd wanneer u URI.toASCIIString () aanroept.
  • File.toURI () is slechter dan Path.toUri () omdat File.toURI () retourneert een ongebruikelijke non-RFC 1738 URI (geeft een bestand: / in plaats van file: ///) en formatteert geen URI's voor UNC-paden volgens Formaat van Microsoft. Geen van deze UNC URI's werkt echter in Firefox (Firefox vereist bestand: /////).
  • Het pad is strenger dan het bestand; je kunt geen ongeldig pad maken van "\. \" Voorvoegsel. "Deze voorvoegsels worden niet gebruikt als onderdeel van het pad zelf", maar ze kunnen worden doorgegeven aan Win32-API's.

URI → bestand: laten we proberen de voorgaande voorbeelden naar bestanden te converteren:

                            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

Nogmaals, met behulp van Paths.get(URI) heeft de voorkeur boven new File(URI), omdat Path in staat is om de UNC URI af te handelen en ongeldige paden met het voorvoegsel \? Maar als je Java 1.7 niet kunt gebruiken, zeg dan new File(URI.getSchemeSpecificPart()) in plaats daarvan.

Trouwens, doe het niet gebruik URLDecoder om een ​​bestands-URL te decoderen. Voor bestanden met "+" zoals "file: /// C: /main.c++", URLDecoder zal het veranderen in "C: \ main.c"! URLDecoder is alleen voor het ontleden van application / x-www-form-urlencoded HTML-formulierinzendingen binnen een URI-query (param=value&param=value), niet voor het unquoting van het pad van een URI.

2014-09: bewerkt om voorbeelden toe te voegen.


68
2017-07-25 23:19



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
2018-05-28 21:44



De huidige antwoorden lijken me vreemd.

java.net.URL.getFile

verandert een bestands-URL zoals deze

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

in dit

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

dus je kunt deze constructor gebruiken

new File(url.getFile)

om je het Windows-pad te geven

java.io.File = C:\some\resource.txt

3
2017-08-03 10:13



Zoals gezegd - retourneert getLocation () een URL. Bestand kan eenvoudig een URI naar een pad converteren, dus voor mij is de eenvoudigste manier gewoon gebruik:

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

Natuurlijk, als je echt String nodig hebt, pas het dan aan:

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

U hebt helemaal geen URLDecoder nodig.


3
2018-04-17 15:13



De volgende code is wat je nodig hebt:

String path = URLDecoder.decode("/C:/Users/David/Dropbox/My%20Programs/Java/Test/bin/", "UTF-8");
System.out.println(new File(path).getPath());

2
2018-05-28 21:47



Hallo verward mensen uit de toekomst. Er is een nuance aan de configuratie van het bestandspad hier. Het pad dat u instelt voor TESSDATA_PREFIX wordt intern gebruikt door het programma C ++ tesseract, nietdoor de java-verpakking. Dit betekent dat als je vensters gebruikt, je de leidende schuine streep moet vervangen en alle andere schuine strepen moet vervangen door schuine strepen naar achteren. Een zeer hacky-oplossing ziet er als volgt uit:

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
2017-12-19 17:47