2010-12-27 1 views
1

Wenn eine Drittanbieter-Bibliothek, die ich benutze, versucht, auf eine Datei zuzugreifen, bekomme ich "Fehler beim Öffnen ... Datei ... (Keine solche Datei oder Verzeichnis)" obwohl ich weiß, dass die Datei in der WAR ist . Ich habe sowohl die gepackte (.war) als auch die "explodierte" (Verzeichnis) Bereitstellung ausprobiert, und die Datei ist definitiv da. Ich habe versucht, auch volle Berechtigungen dafür zu setzen. Es ist auf Unix (Ubuntu). Datei ist war/dict/index.sense und der Fehler ist "dict/index.sense (keine solche Datei oder Verzeichnis)".Anfänger-Servlet-Frage: Zugriff auf Dateien in einem WAR, welcher Pfad?

Es funktioniert gut auf meinem Windows-Computer, wenn es im gehosteten Modus als GWT-App von Eclipse ausgeführt wird, nur nicht, wenn ich es zur Bereitstellung auf den Unix-Rechner übertrage.

Meine Frage ist: Hat jemand das schon einmal erlebt und/oder gibt es Unterschiede im relativen Pfad, die ich in Betracht ziehen sollte, d. H. Was ist der Root-Pfad für relativen Dateizugriff in einem Krieg?

+2

zeigen Sie uns etwas Code (der hoffentlich servletContext.getRealPath enthält) – Thilo

+0

Es ist eine Bibliothek von Drittanbietern, die versucht, auf die Datei zuzugreifen. Also habe ich keine Kontrolle darüber, wie es das macht.Der einzige Code, den ich einstelle, ist "System.setProperty (" wordnet.database.dir "," dict ");" gemäß ihren Anweisungen zur Verwendung ihrer Bibliothek. – Navigateur

Antwort

0

ich diese Antwort zu BalusC verdanken, aber da ich nicht verstehen, ist es zunächst tat wirklich, vereinfacht ich es:

das Arbeitsverzeichnis (den Ausgangspunkt für relative Pfade) hängt von der Art und Weise der Die Anwendung wird gestartet, Sie haben also keine Kontrolle darüber. Glücklicherweise gibt es eine Möglichkeit, um den absoluten Pfad etwas in Ihrer Web-Anwendung Stammverzeichnis zu erhalten, die sich wie folgt:

getServletContext().getRealPath("pathToAnyFileInYourWebAppDocumentRoot.ext") 

(Dies ergibt einen String)

Das ist alles, was Sie tun müssen. Leider funktioniert das nur, wenn Ihre App als Verzeichnis bereitgestellt wird und nicht als .war-Datei (wobei null zurückgegeben wird).

(Siehe BalusC's Antwort für einen anderen Weg, und woher diese Antwort kam).

8

Sie sollten sich beim Lesen einer Ressource niemals auf relative Pfade in Datei-IO verlassen. Das Arbeitsverzeichnis hängt nämlich davon ab, wie die Anwendung gestartet wird. Sie haben insgesamt keine Kontrolle darüber. Verwenden Sie in Datei-IO immer absolute Pfade.

Die normalen Ansätze sind:

  • die Ressource in dem Classpath Setzen oder seinen Pfad zum Classpath hinzufügen. Dann können Sie es vom Klassenlader wie folgt erhalten:

    String classPathLocation = "filename.ext"; 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    InputStream input = classLoader.getResourceAsStream(classPathLocation); 
    // ... 
    

    Beachten Sie die Art, wie der Klassenlader und die Ressource erhalten wird. Sie sollten es nicht von der aktuellen Klasse wie getClass().getResourceAsStream() erhalten. In einem WAR gibt es nämlich möglicherweise Mittel von mehreren Klassenladern. Der Klassenlader der aktuellen Klasse weiß möglicherweise nicht über die gewünschte Ressource per se, den Kontext wird es.

  • Legen Sie die Ressource in webcontent (dort wo der Ordner WEB-INF ist und alle anderen öffentlichen Webressourcen). Dann können Sie den absoluten Pfad wie folgt erhalten, die Sie gerade in der üblichen Datei IO-Code weiterverwenden:

    String relativeWebPath = "/filename.ext"; 
    String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath); 
    InputStream input = new FileInputStream(absoluteDiskPath); 
    // ... 
    

    Beachten Sie, dass dies nur funktioniert, wenn der Krieg expandiert, sonst es nur null zurück.

Verwandte Themen