Input/Output Jar-Datei zur Laufzeit erweitern

Hallo Leute!
Ich wollte eine jar-datei zur Laufzeit um ein Bild erweitern.
Das geht nur im Programm, da der Benutzer entscheidet, wie das Bild aussehen soll.
An anderer Stelle kann es aus bestimmten Gründen nicht gespeichert werden.

Ich habe es schon versucht über
Java:
... new File("c:/.../desktop/test.jar/bild.png").createFile();
aber dann kommt eine FileNotFound Exception.
Ich habe schon gegooglet und hier im Forum nachgeschaut, aber da steht immer was vom erstellen,
ich will die aber nur um eine datei erweitern.

Hat da jemand eine Idee?
 
Du kannst JAR-Dateien in der Ausfürhung nicht verändern. Und selbst wenn dies ginge: mit File wirst du nicht weit kommen, dieses ist nur für Dateien im Dateisystem gedacht. JAR-Dateien lassen sich mit [japi]JarFile[/japi] und den dazugehörigen Streams verarbeiten.
 
Du kannst mit JarFile und den zugehörigen Streams (siehe auch [japi]ZipFile[/japi] - JarFile ist von ZipFile abgeleitet) Jar-Archive erstellen, auslesen und ändern, solange sich dieses nicht in der Ausführung befindet.
Anders ausgedrückt: du kannst das .jar deiner Anwendung nicht während der Laufzeit ändern.
 
Und nicht zu vergessen: [japi]ZipInputStream[/japi] und [japi]ZipOutputStream[/japi] (bzw. deren Jar-Äquivaelnte mit Jar statt Zip).
 
Dann solltest du daran arbeiten - Englisch ist die wichtigste Sprache in der Informatik.
Prinzipiell ist der Vorgang relativ einfach. Nehmen wir an, du willst ein .jar erstellen (den Use Case Ändern kannst du ja dadurch abdecken, dass du ein vorhandenes .jar Stück für Stück ausliest, änderst und dann wieder heraus schreibst - vielleicht kannst du es auch direkt ändern, aber das müsstest du selbst ausprobieren). Dazu legst du dir einen [japi]JarOutputStream[/japi] an, z. B. so:
Java:
try(JarOutputStream jar = new JarOutputStream(new FileOutputStream("test.jar"))) {
			
		} catch (JarException e) {}
(Exception-Handling nicht vergessen, ich habe es nur aus Platzgründen weggelassen)
Anschließend musst du für jeden Eintrag im .jar ein [c]JarEntry[/c]-Objekt erstellen:
Java:
try(JarOutputStream jar = new JarOutputStream(new FileOutputStream("test.jar"))) {
			JarEntry entry = new JarEntry("test.txt");
		} catch (JarException e) {}
Anschließends übergibst du dem JarOutputStream diesen JarEntry. Damit startest du einen neuen Eintrag im Jar. Alle von nun an geschriebenen Daten wandern in diesen Eintrag:
Java:
try(JarOutputStream jar = new JarOutputStream(new FileOutputStream("test.jar"))) {
			JarEntry entry = new JarEntry("test.txt");
			jar.putNextEntry(entry);
			jar.write("Dies ist ein Test.".getBytes(), 0, 18);
		} catch (JarException e) {}
Natürlich kannst du deinen JarOutputStream auch noch in andere Streams schachteln, damit du nicht die write(byte[], int, int)-Methode verwenden musst. Du musst allerdings darauf achten, auch eine Referenz auf deinen JarOutputStream zu behalten, damit du neue Einträge starten kannst.
Hast du alle Daten, die in den Eintrag kommen, geschrieben, schließt du den Eintrag mittels closeEntry() und kannst den nächsten beginnen.
Lesen funktioniert ähnlich. Du erstellst dir ein JarFile, besorgst dir von diesem deinen gewünschten JarEntry via getJarEntry(String name) (oder eine Auflistung aller JarEntries über entries()) und bekommst einen InputStream zum Lesen von dessen Daten über JarFile#getInputStream(JarEntry). Alternativ kannst du auch den JarInputStream verwenden und die Einträge im Jar dort sequentiell auslesen über getNextJarEntry();
Tipp: willst du ein Verzeichnis anlegen, so muss dessen Name im JarEntry mit einem / enden, z. B. [c]new JarEntry("folder/");[/c]. Dessen Kinder müssen mit vollem Pfad angegeben werden, also z. B. [c]new JarEntry("folder/file.txt");[/c].
 
Jupp, JarFile und die Jar*Streams erben von den entsprechenden Zip-Klassen und fügen nur wenige Methoden hinzu.
 
Danke erst mal für deine sehr hilfreiche Antwort! :toll:

Wenn die test.jar aus deinem Beispiel schon existiert,
könnte man nicht mit
Code:
jar.putNextEntry(entry);
usw. gleich dem Jar-Archiv eine Datei hinzufügen?
Oder wird dann ein komplett neues Archiv mit nur der Datei erstellt bzw. eine Exception ausgeworfen?
 

Neue Themen


Zurück
Oben