Resource to File

Hallo Leute.
(tut mir leid das ich das forum bemühe :smiley: ja ich habe schon geoogelt, aber bis jetzt nichts brauchbares gefunden)

Ich suche nach einem eleganten weg, aus einer url ein file objekt zu machen.
Das Problem ist:

Eine url von getResource() gibt in eclipse file: … zurück. Wenn ich dieses file: einfach abschneide, kann ich damit ein
file objekt machen. Aus einer jar datei heraus gibt mir das aber folgendes: jar:file … das heisst ich müsste prüfen ob der anfang
file: oder jar:file: ist und das wegschneiden… aber das ist nicht wirklich elegant oder?

new File(url.toUri()) geht nicht in einer jar. (uri is not hierachical oder so)
new File(url.getFile()) geht ebenfalls nicht, selbes problem wie oben, ide [nichts]C:/ … aus einer jar file:C:/ …

Also, wie macht man das am besten?
Warum ich ein file brauche: Weil ich einen ganzen ordner auslesen will,
und alle dateien daraus zu speichern habe… Und das geht mit getResource ja keineswegs, oder vielleicht doch?
mit einem file mach ich immer listFiles()…

vielen Ddank!

ein file/directory in einem jar ist nicht ein File Objekt. Du kannst nicht die File methoden auf dateien im jar anwenden. Du kannst dir einen Stream von denen holen und damit arbeiten oder dateien entpacken und dann per File objekte daraufgreifen

und wie hol ich mir einen stream davon?

Habs nur überflogen, ich denke

getClass().getResource("...");

oder

getClass().getResourceAsStream("...");

ist das, was du suchst.

aber ich muss ja einen ganzen ordner auslesen, wär vllt gut wenn dus dir ganz durch liest, wenn du zeit hast :confused:

[QUOTE=mymaksimus]Hallo Leute.
(tut mir leid das ich das forum bemühe :smiley: ja ich habe schon geoogelt, aber bis jetzt nichts brauchbares gefunden)[/QUOTE]
glaub ich nicht so ganz :wink:
http://lmgtfy.com/?q=reading+directory+jar

URL url = MyClass.class.getClassLoader().getResource("standardSourceFolder\\dir1\\dir2");
File file = new File( url.toURI() );

Falls du es selber nicht gefunden hast :wink:

…falls du es selber nicht gelesen hast…

Genauer gesagt diese Exception:


C:\Users\Administrator\Desktop>java -jar Homework.jar
java.lang.IllegalArgumentException: URI is not hierarchical
        at java.io.File.<init>(Unknown Source)
        at homework.moonface.src.Moonface.loadSounds(Moonface.java:94)
        at homework.moonface.src.Moonface.<init>(Moonface.java:55)
        at control.Overview.main(Overview.java:16)

Witzig :wink: bei mir gehts! Hatte eben das gleiche Problem und dann: eine Lösung gesucht, eine gefunden, diesen Thread gefunden und die gefundene Lösung gleich mal gepostet…

Welche Art von Stream benutzt du denn?

getClass().getResource() halt

Ha, ich nehme alles zurück und behaupte das Gegenteil!
Ich hab genau das gleiche Problem wie du und bettele jetzt mit um eine Antwort :wink:

Also dann hat jemand eine Lösung :stuck_out_tongue:

es funktioniert nichts so wie ich es will… hab mir schon classLoader().getResources() angesehen aber damit bekome ich auch nur den „ordner“…
es muss doch irgendwie möglich sein einen ordner voller daten auszulesen, ohne die namen zu wissen, und das in einer jar :frowning:

Weißt du denn wie man eine File schreibt und ließt wenn man den Namen kennt? Das würde mir helfen…

wenn man den namen kennt, lesen? Was genau den lesen? es hängt davon ab. Bilder mache ich normalerweise mit ImageIO.read(getClass().getResource(pfadzumbild));

Ja, das meine ich auch nicht…
Ich meinte eine Textfile! Da ist es nicht so einfach das es keine Methode alla StringIO.read(URL) gibt :slight_smile:

Ich frag jetzt mal explizit nach, weil das bislang nicht im geringsten klar ist. Befinden sich die Dateien bzw. die Ordner zwangsläufig in dem Jar? Wozu willst du die auslesen bzw. was heißt hier “speichern”? Willst du etwa einen bestimmten Ordner in deinem Jar auspacken? Wenn ja, dann schau dir mal die Klasse JarFile an, denn File bezieht sich auf Dateien, die direkt auf dem Dateisystem liegen und funktioniert bei verpackten Dateien nicht. Da braucht man speziell für das Archiv bestimmte Klassen, z.B. JarFile. Alternativ könnte man auch NIO2 nutzen anstatt die “alten” Kamellen, denn es könnte gut sein, dass es da auch ein FileSystem für Jar-Dateien gibt und dann wäre der Umgang einheitlich. Das muss ich aber selbst nachher mal nachschauen, wenns bis dahin nicht geklärt worden ist.
@IDC
StringIO gibt es nicht, aber Files mit ihren Methoden readAllLines(Path, Charset) und readAllBytes(Path). Die Klasse besitzt noch eine ganze Palette mehr an Methoden, die viele Anwendungsfälle zu Einzeilern werden lassen.

nein. ich habe ein projekt.

project.jar
—src
------Main.class
------Second.class
—res
-----img
--------p1.png
--------p2.png
--------bildX.png
--------affe.png

so und in main.java will ich eine arraylist anlegen, die alle bilder aus /img enthält.

Moin,

vermutlich möchtest Du die Bilder aus Deiner ArrayList später auch anzeigen. Dann bräuchtest Du aber zusätzlich noch eine Abbildung zwischen dem Index des Arrays und dem gewünschten Bild. Ein einfaches list.get(3) wäre ungünstig, da es jetzt z.B. der Affe wäre, aber wenn Du später ein Bild hinzufügst, etwas anderes.

Du brächtest also etwas das die Bilder benennt. Ich würde das in kleineren Projekten etwa so lösen:


    P1("/res/img/p1.png"),
    P2("/res/img/p2.png"),
    IMAGE_X("/res/img/bildX.png"),
    MONKEY("/res/img/affe.png");

    private final Image image;


    private Images(final String path) {

        this.image = loadImage(path);

    }


    public Image getImage() {

        return image;

    }


    private Image loadImage(final String path) {

        Image image = null;

        try (InputStream is = getClass().getResourceAsStream(path)) {

            if (is == null)
                throw new RuntimeException("Image not found: " + path);

            image = ImageIO.read(is);

            if (image == null)
                throw new RuntimeException("Image invalid: " + path);

        } catch (final IOException e) {

            throw new RuntimeException("Resource not readable: " + path, e);

        }

        return image;

    }

}```

Der Zugriff auf die einzelnen Bilder wäre dann möglich über:

```Images.MONKEY.getImage()```

Viele Grüße
Fancy

[QUOTE=mymaksimus]nein. ich habe ein projekt.

project.jar
—src
------Main.class
------Second.class
—res
-----img
--------p1.png
--------p2.png
--------bildX.png
--------affe.png

so und in main.java will ich eine arraylist anlegen, die alle bilder aus /img enthält.[/QUOTE]
Wie Akeshihiro schon sagte: du kannst File nicht für Einträge in einem JAR verwenden, sondern nur für Dateien im Dateisystem. Du hast zwei Möglichkeiten:
[ol]
[li]Nutze JarFile bzw. dessen Methode entries() um dir ALLE Einträge des Jars zu besorgen. Über die so erhaltenen JarEntry-Objekte kannst du alle Einträge raussuchen, deren Pfad mit “res/img” beginnt und diese dann weiterverarbeiten. Diese Methode sollte auf allen relevanten Java-Versionen funktionieren.[/li][li]Wenn du auf Java 7 arbeitest und keine Kompatibilität zu älteren Versionen benötigst, kannst du NIO2 verwenden und mit dem FileSystem arbeiten, welches eine Abstraktion von Archiven als Dateisystem bietet: http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html[/li][/ol]
Ansonsten ist Fancys Lösung auch gut, sofern du nicht über viele Bilder verfügst und diese tatsächlich automatisch auslesen möchtest.

Wenn die Bezeichnungen der Dateien einem Schema folgen (p1.png, p2.png, p3.png usw) kann man die auch mit einer Schleife auslesen.