web-dev-qa-db-fra.com

Conversion de fichier Java: // URL en chemin de fichier (...), indépendant de la plate-forme, y compris les chemins UNC

Je développe une application indépendante de la plateforme. Je reçois une URL de fichier * . Sous Windows, ce sont:

  • file:///Z:/folder%20to%20file/file.txt

  • file://Host/folder%20to%20file/file.txt (un chemin UNC)

J'utilise new File(URI(urlOfDocument).getPath())qui fonctionne bien avec le premier et aussi sur Unix, Linux, OS X, mais ne fonctionne pas avec les chemins UNC.

Quelle est la méthode standard pour convertir un fichier: les URL en chemins de fichiers (..), compatibles avec Java 6?

......

* Remarque: je reçois ces URL de OpenOffice/LibreOffice (XModel.getURL ()).

20
Christian Fries

Sur la base de l'allusion et du lien fournis dans la réponse de Simone Giannis, voici mon hack pour résoudre ce problème.

Je teste sur uri.getAuthority (), car le chemin UNC signalera une autorité. Il s’agit d’un bogue - je m’appuie donc sur l’existence d’un bogue, qui est diabolique, mais il semble que cela restera pour toujours (car Java 7 résout le problème dans Java.nio.Paths).

Remarque: dans mon contexte, je recevrai des chemins absolus. J'ai testé cela sous Windows et OS X.

(Toujours à la recherche d'une meilleure façon de le faire)

package com.christianfries.test;

import Java.io.File;
import Java.net.MalformedURLException;
import Java.net.URI;
import Java.net.URISyntaxException;
import Java.net.URL;

public class UNCPathTest {

    public static void main(String[] args) throws MalformedURLException, URISyntaxException {
        UNCPathTest upt = new UNCPathTest();

        upt.testURL("file://server/dir/file.txt");  // Windows UNC Path

        upt.testURL("file:///Z:/dir/file.txt");     // Windows drive letter path

        upt.testURL("file:///dir/file.txt");        // Unix (absolute) path
    }

    private void testURL(String urlString) throws MalformedURLException, URISyntaxException {
        URL url = new URL(urlString);
        System.out.println("URL is: " + url.toString());

        URI uri = url.toURI();
        System.out.println("URI is: " + uri.toString());

        if(uri.getAuthority() != null && uri.getAuthority().length() > 0) {
            // Hack for UNC Path
            uri = (new URL("file://" + urlString.substring("file:".length()))).toURI();
        }

        File file = new File(uri);
        System.out.println("File is: " + file.toString());

        String parent = file.getParent();
        System.out.println("Parent is: " + parent);

        System.out.println("____________________________________________________________");
    }

}
9
Christian Fries

En s'appuyant sur le commentaire de @ SotiriosDelimanolis, voici une méthode pour traiter les URL (telles que fichier: ...) et les non-URL (telles que C: ...), à l'aide de FileSystemResource de Spring:

public FileSystemResource get(String file) {
    try {
        // First try to resolve as URL (file:...)
        Path path = Paths.get(new URL(file).toURI());
        FileSystemResource resource = new FileSystemResource(path.toFile());
        return resource;
    } catch (URISyntaxException | MalformedURLException e) {
        // If given file string isn't an URL, fall back to using a normal file 
        return new FileSystemResource(file);
    }
}
2
Markus Pscheidt

Java (au moins 5 et 6, les chemins Java 7 étant les plus résolus) a un problème avec UNC et URI. L'équipe Eclipse l'a résumé ici: http://wiki.Eclipse.org/Eclipse/UNC_Paths

Dans les javadocs Java.io.File, le préfixe UNC est "////" et Java.net.URI gère le fichier: //// hôte/chemin (quatre barres obliques).

Vous trouverez plus de détails sur les raisons pour lesquelles cela se produit et sur les problèmes possibles qu’elles entraînent avec d’autres méthodes URI et URL, dans la liste des bogues à la fin du lien indiqué ci-dessus.

À l'aide de ces informations, l'équipe Eclipse a développé la classe org.Eclipse.core.runtime.URIUtil, dont le code source peut probablement aider lors de l'utilisation de chemins UNC.

1
Simone Gianni

Pour Java 8, la méthode suivante fonctionne:

  1. Former un URI à partir d'une chaîne de fichier URI
  2. Créer un fichier à partir de l'URI (pas directement à partir d'une chaîne d'URI, la chaîne d'URI absolue ne sont pas des chemins)

Voir extrait de code ci-dessous

    String fileURiString="file:///D:/etc/MySQL.txt";
    URI fileURI=new URI(fileURiString);
    File file=new File(fileURI);//File file=new File(fileURiString) - will generate exception

    FileInputStream fis=new FileInputStream(file);
    fis.close();
0
Ironluca