web-dev-qa-db-fra.com

Convertir l'URL en nom de fichier Windows normal Java

Existe-t-il un moyen de convertir ceci:

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

dans ça ?:

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

J'utilise le code suivant, qui renverra le chemin complet de l'archive .JAR ou le répertoire/bin.

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

Le problème est que getLocation() renvoie un URL et j'ai besoin d'un nom de fichier Windows normal. J'ai essayé d'ajouter ce qui suit après getLocation():

toString() et toExternalForm() renvoient tous les deux:

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

getPath() renvoie:

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

Notez le %20 Qui doit être converti en espace.

Existe-t-il un moyen rapide et facile de le faire?

52
David

La recommandation actuelle (avec JDK 1.7+) est de convertir URL → URI → Chemin. Donc, pour convertir une URL en fichier, vous diriez Paths.get(url.toURI()).toFile(). Si vous ne pouvez pas encore utiliser JDK 1.7, je recommanderais new File(URI.getSchemeSpecificPart()).

Conversion de fichier → URI: je vais d'abord vous montrer quelques exemples d'URI que vous obtiendrez probablement en Java.

                          -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

Quelques observations sur ces URI:

  • Les spécifications URI sont RFC 1738: URL , remplacé par RFC 2396: URI , remplacé par RFC 3986: URI . (Le WHATWG a également un spécification URI , mais il ne spécifie pas comment les URI de fichier doivent être interprétés.) -quoté lorsque vous appelez URI.toASCIIString ().
  • File.toURI () est pire que Path.toUri () car File.toURI () renvoie un URI non RFC 1738 inhabituel (donne le fichier:/au lieu du fichier: ///) et ne le fait pas formater les URI pour les chemins UNC selon format préféré de Microsoft . Cependant, aucun de ces URI UNC ne fonctionne dans Firefox (Firefox nécessite le fichier: /////).
  • Le chemin est plus strict que File; vous ne pouvez pas construire un chemin invalide à partir de préfixe "\. \" . "Ces préfixes ne sont pas utilisés dans le cadre du chemin d'accès lui-même", mais ils peuvent être transmis aux API Win32.

Conversion d'URI → fichier: essayons de convertir les exemples précédents en fichiers:

                            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

Encore une fois, l'utilisation de Paths.get(URI) est préférable à new File(URI), car Path est capable de gérer l'URI UNC et de rejeter les chemins non valides avec le préfixe \? \. Mais si vous ne pouvez pas utiliser Java 1.7, dites new File(URI.getSchemeSpecificPart()) à la place.

Soit dit en passant, n'utilisez pas URLDecoder pour décoder l'URL d'un fichier. Pour les fichiers contenant "+" tels que "fichier: /// C: /main.c++", URLDecoder le transformera en "C:\main.c"! URLDecoder est uniquement destiné à l'analyse des soumissions de formulaires HTML application/x-www-form-urlencoded dans une requête d'URI (param=value&param=value), pas pour ne pas citer le chemin d'un URI.

2014-09: édité pour ajouter des exemples.

72
yonran
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
Bozho

Comme cela a été mentionné - getLocation () renvoie une URL. Le fichier peut facilement convertir un URI en chemin, donc pour moi, le moyen le plus simple est simplement d'utiliser:

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

Bien sûr, si vous avez vraiment besoin de String, modifiez simplement pour:

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

Vous n'avez pas du tout besoin de URLDecoder.

3
Mi-La

Bonjour les gens confus du futur. Il y a une nuance à la configuration du chemin de fichier ici. Le chemin que vous définissez pour TESSDATA_PREFIX est utilisé en interne par le programme tesseract C++, pas par le wrapper Java. Cela signifie que si vous utilisez Windows, vous aurez besoin pour remplacer la barre oblique principale et remplacer toutes les autres barres obliques par des barres obliques inversées. Une solution de contournement très hacky ressemble à ceci:

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
xtro

Les réponses actuelles me semblent louche.

Java.net.URL.getFile

transforme une URL de fichier comme celle-ci

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

dans ce

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

afin que vous puissiez utiliser ce constructeur

new File(url.getFile)

pour vous donner le chemin Windows

Java.io.File = C:\some\resource.txt
2
Pete Montgomery

Le code suivant est ce dont vous avez besoin:

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