2009-09-01 7 views
6

(J'ai un problème que j'ai illustré dans la question this mais je n'ai pas eu de bonnes réponses.) J'ai affiné mon problème et essayé d'éditer la question initiale pour refléter cela mais je suppose que la façon dont SO affiche les questions sans réponse. pas moyen de le faire revivre, donc je publie ma bonne question à nouveau).Impossible de lancer un fichier sur un réseau à l'aide de Java Desktop?


I ont un fichier qui se trouve sur un emplacement réseau partagé:

"\\KUROSAVVAS-PC\Users\kuroSAVVAS\Desktop\New  Folder\Warsaw Panorama.JPG" 

(Les espaces sont là intentionnellement)

Le code suivant:

import java.awt.Desktop; 
import java.io.File; 
import java.io.IOException; 

public class Test { 

    public static void main(String[] args) { 
     try { 
      String s = "\\\\KUROSAVVAS-PC\\Users\\kuroSAVVAS\\Desktop\\New  Folder\\Warsaw Panorama.jpg"; 
      File f = new File(s); 
      System.out.println(f.exists()); 
      Desktop.getDesktop().open(f); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

Affiches à la console sur laquelle le fichier existe (System.out.println (f.exists());) mais jette cette exception! :

java.io.IOException: Failed to open file:////KUROSAVVAS-PC/Users/kuroSAVVAS/Desktop/New%20%20%20%20%20Folder/Warsaw%20%20%20%20Panorama.jpg. Error message: The system cannot find the file specified. 

    at sun.awt.windows.WDesktopPeer.ShellExecute(WDesktopPeer.java:59) 
    at sun.awt.windows.WDesktopPeer.open(WDesktopPeer.java:36) 
    at java.awt.Desktop.open(Desktop.java:254) 
    at Test.main(Test.java:13) 

Quelqu'un a-t-il une idée de ce qui pourrait arriver? J'ai tout essayé depuis la création d'URI jusqu'à leur décodage par la suite ... Rien ne fonctionne.

+0

et ne le même chemin de fichier (à savoir avec des espaces) fonctionne lorsque le fichier est local sur votre ordinateur (c.-à-d. sur C :)? Le problème est-il lié au système de fichiers réseau? –

+0

Si je colle ce "\\\\ KUROSAVVAS-PC \\ Users \\ kuroSAVVAS \\ Bureau \\ Nouveau dossier \ Warsaw Panorama.jpg" dans la boîte de dialogue "Exécuter", le fichier s'ouvre normalement. Dans cet exemple, le partage réside également sur mon disque local, mais en général il devrait fonctionner avec n'importe quel emplacement réseau. –

+0

(les espaces ont été automatiquement supprimés sur mon commentaire précédent, ils sont là ...) Je voulais aussi dire que je suis authentifié contre le partage –

Répondre

4

Il semble qu'il y ait un bogue lorsque vous essayez d'accéder à une ressource sur un lecteur réseau avec des espaces dans le chemin. Voir this entry dans la base de données de bogues de Sun.

Étant donné que le bogue a déjà un an, je ne pense pas que vous obtiendrez une solution de sitôt. Essayez la dernière VM. Si cela ne vous aide pas, essayez d'obtenir la source pour WDesktopPeer. Au lieu d'encoder le chemin, essayez de le garder tel quel (avec des barres obliques inverses et tout) et placez des guillemets autour de celui-ci. Cela pourrait fonctionner.

[EDIT] Plus précisément, ne pas remplacer \ avec /, ne précédez file:// et laisser les espaces car ils sont (au lieu de les remplacer par %20)

+0

vous voulez dire dans la source WDesktopPeer? –

+1

Oui. Corrigez la source de WDesktopPeer pour laisser le chemin seul et transmettez-le sans modification du code natif du système d'exploitation. –

8

solution Java 6:

public static void launchFile(File file) { 
    if (!Desktop.isDesktopSupported()) 
     return; 
    Desktop dt = Desktop.getDesktop(); 
    try { 
     dt.open(file); 
    } catch (IOException ex) { 
     // this is sometimes necessary with files on other servers ie 
     // \\xxx\xxx.xls 
     launchFile(file.getPath()); 
    } 
} 

// this can launch both local and remote files 
public static void launchFile(String filePath) { 
    if (filePath == null || filePath.trim().length() == 0) 
     return; 
    if (!Desktop.isDesktopSupported()) 
     return; 
    Desktop dt = Desktop.getDesktop(); 
    try { 
     dt.browse(getFileURI(filePath)); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

// generate uri according to the filePath 
private static URI getFileURI(String filePath) { 
    URI uri = null; 
    filePath = filePath.trim(); 
    if (filePath.indexOf("http") == 0 || filePath.indexOf("\\") == 0) { 
     if (filePath.indexOf("\\") == 0){ 
      filePath = "file:" + filePath; 
      filePath = filePath.replaceAll("#", "%23"); 
     } 
     try { 
      filePath = filePath.replaceAll(" ", "%20"); 
      URL url = new URL(filePath); 
      uri = url.toURI(); 
     } catch (MalformedURLException ex) { 
      ex.printStackTrace(); 
     } catch (URISyntaxException ex) { 
      ex.printStackTrace(); 
     } 
    } else { 
     File file = new File(filePath); 
     uri = file.toURI(); 
    } 
    return uri; 
} 

Cette réponse était sur le rapport de bogue, mais je l'ai édité pour corriger quand il y a un hachage.

+1

fonctionne comme un charme, merci M.Zammbi. –

8

Avec java 7 vous pouvez le faire

public static void main(String[] args) throws IOException { 
    String s = "\\\\KUROSAVVAS-PC\\Users\\kuroSAVVAS\\Desktop\\New  Folder\\Warsaw Panorama.jpg"; 
    Path p = Paths.get(s); 
    Desktop.getDesktop().browse(p.toUri()); 
} 
6

TL; DR de ZAMMBI's answer (+1 BTW).(Utilisation de Java 6)

Cela fonctionne, comme prévu

Desktop.getDesktop().open(new File("\\\\host\\path_without\\spaces.txt")); //works 

Cela échoue, en raison d'un bug Java connu:

Desktop.getDesktop().open(new File("\\\\host\\path with\\spaces.txt")); //fails <shakes fist> 

Ce travail autour de travaux

Desktop.getDesktop().browse(new URI("file://host/path%20with/spaces.txt")) //works (note slash direction and escape sequences) 

Cette solution semble fonctionner, mais pas:

Desktop.getDesktop().browse((new File("\\\\host\\path with\\spaces.txt")).toURI()); 

Ce travail autour fonctionne et semble être la forme la plus générale:

File curFile = new File("\\\\host\\path with\\or_without\\spaces\\local or network.txt"); 
Desktop.getDesktop().browse(new URI(curFile .toURI().toString().replace("file:////","file://"))); 
Questions connexes