1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

[Java] relative Pfade in einem jar-Archiv?

Dieses Thema im Forum "OS X-Developer" wurde erstellt von Wikinator, 13.11.05.

  1. Wikinator

    Wikinator Adams Parmäne

    Dabei seit:
    21.08.04
    Beiträge:
    1.297
    Hallo,

    ich habe ein Programm, das normal als .class-Datei und gut läuft.
    es macht nichts anderes als die Datei "Property.txt" mit Werten zu füllen. Ich greife dabei so auf die Datei zu:
    Code:
    BufferedWriter out = new BufferedWriter(new FileWriter("Property.txt"));
    wenn ich alles (die .class-datei und property.txt) in ein jar-archiv verpacke, wird nicht die Datei "Property.txt" im jar-archiv sondern die Datei "Property.txt" im source-ordner editiert. Wieso?
     
  2. Wikinator

    Wikinator Adams Parmäne

    Dabei seit:
    21.08.04
    Beiträge:
    1.297
    *hochschieb*
     
  3. Demo

    Demo Süssreinette (Aargauer Herrenapfel)

    Dabei seit:
    02.04.04
    Beiträge:
    411
    Ganz im Groben und zum weiterkniffeln. Du musst/kannst dies ueber einen Klassenlader bzw. Stream loesen.
    Code:
    Class A
    {
    
    /*-------------schnipp-------------------*/
    void laden()
    {
    InputStream in = getClass().getResourceAsStream("propertie.txt");
    }
    
    /*---------------------------------------*/
    }
    
    Du bekommst also Deine Datei als Ressource ueber den sogenannten Klassenlader, deralle Dateien entdeckt, die im Pfad des Klassenladers eingetragen ist. Das gilt zum Beispiel fuer Jar Archive, hier ist alles vom Klassenlader verfuegbar. Reicht der Denkanstoss ?
     
  4. commander

    commander Baldwins roter Pepping

    Dabei seit:
    25.02.04
    Beiträge:
    3.210
    Das kommt auf Deinen Klassenpfad an - so, wie Du das angegeben hast, liegt die Datei einfach im Working Directory.

    Eine Textdatei aus einem Jar kannst Du sowieso nicht einfach so zurückschreiben.

    Ressourcen legt man z.B. in einem eigenen Ordner resources/ ab, wenn Dus gezippt haben willst und schreiben willst, dann muss Du in den saueren Apfel beissen und Dir das Zipfile auspacken, und das neue Entrie hinufügen und wieder wegschreiben. Wie sinnvoll das ist, musst Du selbst entscheiden.

    Gruß,

    .commander
     
  5. Wikinator

    Wikinator Adams Parmäne

    Dabei seit:
    21.08.04
    Beiträge:
    1.297
    @commander: auspacken und wieder einpacken, wäre etwas umständlich, gibt es keine andere möglichkeit?

    das habe ich auch schonmal versucht, aber damit kann ich doch keinen OutputStream bekommen, oder?
     
  6. commander

    commander Baldwins roter Pepping

    Dabei seit:
    25.02.04
    Beiträge:
    3.210
    Erstmal zum Stream: ein getResource(String name) liefert eine URL, aus der Du dann den Filenamen beziehen kannst und gegebenenfalls ein File erzeugen kannst. ABER: In Deinem Fall wirst Du an der URL schon sehehn, dass das Protokoll zwar file: lautet aber ein '!' im Pfad ist. Alles nach dem '!' liegt in einem Jar.

    Und: Nein, soweit ich weiß gibt es keine andere Lösung. Aber Du kannst ja das Propertyfile verschlüsseln, wenns keiner einfach so lesen können soll.

    Gruß,

    .commander
     
  7. Wikinator

    Wikinator Adams Parmäne

    Dabei seit:
    21.08.04
    Beiträge:
    1.297
    das lesen wäre nicht das problem, sondern die plattforumunabhänigkeit. wo soll ich es sonst hinspeichern?
    d.h. ich kann auf files in einem jar nur lesend zugreifen?
     
  8. Demo

    Demo Süssreinette (Aargauer Herrenapfel)

    Dabei seit:
    02.04.04
    Beiträge:
    411
    Eine einfache Loesung waere ein Ordner im Home Verzeichnis des Users. Unter Linux/Unix waere zum Beispiel ein versteckter Ordner machbar (.Ordner), unter Windows wuerde man den dann halt sehen.
     
  9. commander

    commander Baldwins roter Pepping

    Dabei seit:
    25.02.04
    Beiträge:
    3.210
    Wie gesagt, normalerweise würde ich Resourcen immer in einen getrennten Ordner unterhalb des Programmordners legen - bei Mac wird das dann sowieso unsichtbar, und Winuser sind Chaos gewöhnt. (Schau Dir mal den jar-Bundler in den Developertools an! Schau Dir mal die Struktur an, die dieser erzeugt, da bieten sich einige gute Plätze für den Resourcenordner an.).

    Also ungefähr so:

    Code:
    
    Programmordner/ 
        - libs/
        - resource/
    
    Wenn Du dem Javaaufruf einfach ein ./resources mit in den Klassenpfad gibst, dann kannst Du in diesem Verzeichniss rumturnen, Files anlegen, löschen - wie Du lustig bist, und kannst trotzdem sicher über den Classloader zugreifen, sodaß Du nicht an festverdrahtete Pfade gebunden bist. Denn wenn Du weißt, daß in Deinem Klassenpfad die Datei meine.properties rumkugeln, dann holst Du Dir die mit dem (übrigens korrekterem als ein getClass() ) Aufruf:

    Code:
    
    URL meineUrl = Thread.currentThread().getContextClassLoader().getResource("meine.properties");
    
    File meinFile;
    
    //Absichern: ist vorhanden, ist ein File, und ist nicht in einem JAR!
    if(meineUrl != null && meineUrl.getFile() != null && meineUrl.getFile().indexOf("!") == -1)
      meinFile = new File(meineUrl.getFile());
    
    So, nun kannst Du auf dem File rumhühnern. Wenn Du später die Ordnerstruktur ändern willst, musst Du nur diese anderen Ordner in den Klassenpfad aufnehmen, aber am Code nichts ändern.

    btw: getResource() verlangt einen relativen Pfad, nicht nur den Namen (also: properties/meine.properties) falls das gesuchte File da liegen würde: resources/properties/meine.properties und resources/ im Klassenpfad ist)

    Gruß,

    .commander
     
    #9 commander, 14.11.05
    Zuletzt bearbeitet: 14.11.05
  10. Wikinator

    Wikinator Adams Parmäne

    Dabei seit:
    21.08.04
    Beiträge:
    1.297
    hm, ich bin irgendwie verwirrt.
    ist der Programmordner ein jar-archiv oder wo ist das jar-archiv? ansich kann es auch in das unterverzeichnis "resources", nur ist es dann doch immer noch in einem jar-archiv.
     
  11. commander

    commander Baldwins roter Pepping

    Dabei seit:
    25.02.04
    Beiträge:
    3.210
    Ok, nochmal etwas ausführlicher. Es gibt sicher verschiedene Wege, eine Javaapplikation zu strukturieren, ich mache das aber meistens so:

    Du nimmst einen übergeordneten Ordner an, beim Entwickeln einfach den Ordner des Projekts, bei einem fertigen Programm einfach einen Ordner MeineApplikation.app/ z.B.

    Darunter hast Du ein libs/ Verzeichnis, in das alle jars, egal ob extern oder Deine liegen. In den jars sind NUR Klassen und _unveränderliche_ Resourcen wie Übersetzungen und Bilder usw, obwohl ich die immer getrennt in ein zip legen würde. Diese Files nimmst Du _einzeln_ in deinen Klassenpfad mit auf.

    Ressourcen wie dein Propertyfile, in die also zur Laufzeit geschrieben werden soll, lege ich in ein Verzeichnis resources/ , das dann ebenfalls in den Klassenpfad kommt, also z.B. ein java -cp ./resources/:./lib/meins.jar:./lib/externes.jar. Du nimmst als den _Ordner_ resources/ in den Klassenpfad auf!

    Wenn Du nun in das resources/ Verzeichnis dein Propertyfile ablegst (wegen mir anfangs leer), dann kannst Du wie beschrieben über den Classloader zugreifen. Das ist übrigens die sichereste und standardmässigste Vorgehensweise.

    Wenn Du den jar-Bundler verwendest, muss Du den ganzen Summs eben entsprechend dort in den Klassenpfad aufnehmen.

    Das bauen von solchen Applikation erledigt bei mir idR die Scriptsprache ANT, solltest Dir irgendwann mal anschauen, wenn Dir das jaren und zippen und rumkopieren zum Hals raushängt. ;)

    Gruß,

    .commander
     
    #11 commander, 14.11.05
    Zuletzt bearbeitet: 14.11.05
  12. Wikinator

    Wikinator Adams Parmäne

    Dabei seit:
    21.08.04
    Beiträge:
    1.297
    danke für die ausführliche Arbeit, auf Dauer wäre ant wohl wirklich besser o_O
     
  13. commander

    commander Baldwins roter Pepping

    Dabei seit:
    25.02.04
    Beiträge:
    3.210
    Äh, und nun?

    Bedeuted Deine knappe Antwort, daß Du verstanden hast, was ich Dir erklären wollte? Oder daß es Dir zu dumm war, nochmals zu fragen?

    Falls zweiteres: Frag einfach, ich helfe gerne. :-D

    Gruß,

    .commander
     
  14. Wikinator

    Wikinator Adams Parmäne

    Dabei seit:
    21.08.04
    Beiträge:
    1.297
    es heißt, ich hab's soweit verstanden und bin am umsetzen. :-D
     

Diese Seite empfehlen