Gibt es eine möglichkeit Dateien aus der jar datei zu kopieren?

VPChief

Bekanntes Mitglied
Ich habe ein programm erstellt, dass eine datei aus seinem src Ordner kopiert. Beim Starten in der Entwicklungsumgebung (Eclipse) funktioniert es.
So lade ich die Datei

Code:
/Test folder/Test File.exe

Die zu startende datei sollte auch eigentlich ein Icon haben, hat sie aber nicht und ausserdem 0KB

1598723867154.png

Das ist dann die Fehlermeldung die ich beim Starten bekomme

1598723790549.png

So siehts momentan im Jar aus
1598724114590.png

Ich habe den Ordner Test folder (obwohl ich es besser weiss) auch schon neben den src ordner geschoben, dann wars gleich.

Und ich weiss, dass es nicht so einfach ist, wenn auch nicht möglich, aber jede möglichkeit ist willkommen.

Ich hoffe, dass dieses Problem gelöst wird, denn sonst werde ich viele meiner projekte ni fertigstellen können

Danke im vorraus
 
Zuletzt bearbeitet:
So lade ich die Datei

Code:
/Test folder/Test File.exe
Das zeigt nicht wirklich, wie du Datei lädtst. Das ist doch nur ein Pfad.

Sorry, so gebe ich den Pfad zur datei an.

So lade ich die datei:
Code:
  File inF = new  File("/Test folder/Test File.exe");

So kopiere ich:
Java:
JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int returnValue = fileChooser.showOpenDialog(null);
        if (returnValue == JFileChooser.APPROVE_OPTION) {
          File selectedFile = fileChooser.getSelectedFile();
          PrintWriter writer = null;
          try {
        targetFile = new File(selectedFile, "Test File.exe");
        System.out.println(targetFile);
            writer = new PrintWriter(targetFile);
            File outF = new  File("" + targetFile);
            try {
                copyFile(inF, outF);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
          } catch (IOException ae) {
            ae.printStackTrace();
          }  finally {
            if (writer != null) {
              writer.flush();
              writer.close();
            }
          } 
        }
    private static void copyFile(File inF, File outF) throws IOException {
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            inChannel = new FileInputStream(inF).getChannel();
            outChannel = new FileOutputStream(outF).getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } catch (IOException e) {
            throw e;
        } finally {
            try {
                if (inChannel != null)
                    inChannel.close();
                if (outChannel != null)
                    outChannel.close();
            } catch (IOException e) {}
        }
    
    }

java.nio.file.NoSuchFileException: \Test folder.zip
at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:53)
at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:38)
at java.base/sun.nio.fs.WindowsFileSystemProvider.readAttributes(WindowsFileSystemProvider.java:198)
at java.base/java.nio.file.Files.readAttributes(Files.java:1843)
at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1160)
at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:717)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:237)
at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:167)
at java.base/java.util.jar.JarFile.<init>(JarFile.java:347)
at java.base/java.util.jar.JarFile.<init>(JarFile.java:318)
at java.base/java.util.jar.JarFile.<init>(JarFile.java:284)
at test.main(test.java:12)
Exception in thread "main" java.lang.NullPointerException
at test.main(test.java:17)


Schätze das hat damit zu tun, das test folder.zip auch im Jar liegt.

Klasse test.java:

Java:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class test {
    public static void main(String[]args) throws IOException {
    File jarFile = new File("/Test folder.zip");
    File destDir = new File(
            "C:\\Users\\irgendjemand\\Documents\\Test folder");
        java.util.jar.JarFile jar = null;
        try {
            jar = new java.util.jar.JarFile(jarFile);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    java.util.Enumeration enumEntries = jar.entries();
    while (enumEntries.hasMoreElements()) {
        java.util.jar.JarEntry file = (java.util.jar.JarEntry) enumEntries.nextElement();
        java.io.File f = new java.io.File(destDir + java.io.File.separator + file.getName());
        if (file.isDirectory()) { // if its a directory, create it
            f.mkdir();
            continue;
        }
        java.io.InputStream is = null;
        try {
            is = jar.getInputStream(file);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } // get the input stream
        java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
        while (is.available() > 0) {  // write contents of 'is' to 'fos'
            fos.write(is.read());
        }
        fos.close();
        is.close();
    }
    jar.close();
}
}

Oder hab ich hier was falsch verstanden
 
Zuletzt bearbeitet:
Wo hast du denn den Code ausgegraben?

Nur um die Anforderungen richtig zu verstehen: du hast in der Jar eine .exe liegen und möchtest die an irgendeinem, vom Nutzer auswählbaren Pfad speichern?
 
Gebt ihm doch die Lösung dann ist Ruh:
Java:
	void extract(String filename) throws IOException {
		InputStream link = (getClass().getResourceAsStream("/path/resources/" + filename));
		Files.copy(link, new File(filename).getAbsoluteFile().toPath());
	}

Btw. So etwas kann schnell auch mal von einem Virenscanner als verdächtiges Verhalten eingestuft werden...
 
Also mit dem getResourceAsStream kannst du eine Datei aus dem Classpath und somit aus dem jar File öffnen.

Du musst aber natürlich den Pfad und Namen richtig angeben und dabei auch auf Gross-/Kleinschreibung achten.
 
Dann zeig den Inhalt der jar Datei komplett und den genauen Code, denn du versuchst.

Aber dmes muss der Pfad in der jar Datei und der Dateiname genau sichtbar sein.
 
Code:
Java:
package forumjar;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.channels.FileChannel;

import javax.swing.JFileChooser;

public class Test {
    public static void main(String[]args) throws IOException {
        


JFileChooser fileChooser = new JFileChooser();
File inF = new  File("/Test folder/Test File.exe");       
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int returnValue = fileChooser.showOpenDialog(null);
        if (returnValue == JFileChooser.APPROVE_OPTION) {
          File selectedFile = fileChooser.getSelectedFile();
          PrintWriter writer = null;
          try {
       File targetFile = new File(selectedFile, "Test File.exe");
        System.out.println(targetFile);
            writer = new PrintWriter(targetFile);
            File outF = new  File("" + targetFile);
            try {
                copyFile(inF, outF);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
          } catch (IOException ae) {
            ae.printStackTrace();
          }  finally {
            if (writer != null) {
              writer.flush();
              writer.close();
            }
          }
        }
        }
    private static void copyFile(File inF, File outF) throws IOException {
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            inChannel = new FileInputStream(inF).getChannel();
            outChannel = new FileOutputStream(outF).getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } catch (IOException e) {
            throw e;
        } finally {
            try {
                if (inChannel != null)
                    inChannel.close();
                if (outChannel != null)
                    outChannel.close();
            } catch (IOException e) {}
        }
    
    

        
    
}
    
    

}
 
Da hast Du doch nichts von dem umgesetzt, was Dir geschrieben wurde.

Mit File greifst Du auf Dateien im Filesystem zu. Aber das willst Du doch nicht, denn Deine Datei ist innerhalb des jar Files.

Daher statt dessen der Zugriff über getClass().getResourceAsStream.
 

Das ist keine Fehlerbeschreibung. Wie es gehen würde, ist schon in #4 im Link zu finden (inkl. einem Codebeispiel wie in #9. Und der Link findet sich in #9 erneut). Versuche es so und wenn es nicht geht: Zeig den Code mit getResourceAsStream und sag, was genau nicht geht. Dann könnte man Dir weiter helfen.
 
Das zu kopierende File inF habe ich jetzt durch
InputStream inF = (Test.class.getClass().getResourceAsStream("/Test folder/Test File.exe"));
ersetzt und in der copy methode File inFdurch Input Stream inF,Sonst ist alles gleich
Das ist keine Fehlerbeschreibung
befindet sich doch schon in #10 und #12 : Das System kann den angegebenen Pfad nicht finden bei diesen zeilen:

inChannel = new FileInputStream("" + inF).getChannel();
copyFile(inF, outF);
 
Zuletzt bearbeitet:
Du hast eine Lösung auch für das Kopieren bekommen. Warum nutzt Du nicht den Files.copy Aufruf, der Dir gegeben wurde?

Ansonsten: Den Code, den Du zusammen gebastelt hast, muss man nicht groß kommentieren, oder?
Wenn Du nachvollziehen willst, was du da so gemacht hast:
- gib mal einfach "" + inF aus. (z.B. mit System.out.println) ==> "java.io.BufferedInputStream@77468bd9" wobei die Zeichen nach dem @ unterschiedlich sein können ...
- Schau einmal, was für einen String der FileInputStream entgegen nehmen möchte. Und dann überleg, ob die Ausgabe vom oberen Schritt da wohl gültig ist ...

Generell (und stark vereinfacht): Alles was direkt ein File im Klassennamen hat (File, FileInputStream, ...) sind Klassen, die direkt auf Dateiebene arbeiten. Also zur Not einfach einmal im Debugger oder mit System.out Werte anzeigen lassen und dann probieren: Klappt es in der Eingabeaufforderung denn?
Funktioniert ein "DIR java.io.BufferedInputStream@xxxxxxxxxx"? Da kann man also gut etwas spielen.
 
Zuletzt bearbeitet:
Dann hast du den Aufruf nicht so gemacht, wie er dir gesagt wurde, denn da war der zweite Parameter kein File....
 
Gebt ihm doch die Lösung dann ist Ruh:
Java:
	void extract(String filename) throws IOException {
		InputStream link = (getClass().getResourceAsStream("/path/resources/" + filename));
		Files.copy(link, new File(filename).getAbsoluteFile().toPath());
	}

Btw. So etwas kann schnell auch mal von einem Virenscanner als verdächtiges Verhalten eingestuft werden...
Das war der Code und auch der Link in dem Du es auch finden kannst ...
 
Dann hast Du wohl etwas falsch gemacht.

Wenn Du keine Details bringst, dann können wir auch nicht ausführlicher schreiben, was Sache ist. Also wie immer:
- Zeig Deinen Code.
- Zeig den Stacktrace und markiere die Zeile, in der die NPE auftritt.

Oder ist das jetzt nur wieder ein Spielchen und Dir geht es gar nicht mehr um die Sache? Das müsste Dich doch schon so viel Zeit gekostet haben: Da einmal das erlesen der Grundlagen + Herumspielen und Du müsstest das Thema schon lange abgehakt und womöglich "Experte" in dem Bereich geworden sein ...
 
Code:
    private static void copyFile() throws IOException {


File file = new File(targetFile + "VP Kurznotitzen.exe");
if (!file.exists()) {
     InputStream link = (Install.class.getClass().getResourceAsStream("/VP Kurznotitzen 1.3.0/VP Kurznotitzen.exe"));
     Files.copy(link, file.getAbsoluteFile().toPath());
}

Die Stack Trace ist
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
in dieser Zeile Files.copy(link, file.getAbsoluteFile().toPath());
 
Dann noch einmal den Inhalt der jar Datei prüfen:
/VP Kurznotitzen 1.3.0/VP Kurznotitzen.exe
existiert in der jar Datei und ist auch genau so geschrieben (incl. Rechtschreibfehler)?

getResourceAsStream gibt null zurück, wenn der angegebene Pfad nicht gefunden wurde.
 
1598900505026.png
ist jetzt in meinem Projekt, in dem ich es umsetzen will.
Die datei funktioniert, würde sie gerne hier anhängen ist aber kein gültiges format
 
Zuletzt bearbeitet:
Dummi Frage, aber bist du sicher, dass die Datei beim Erstellen des JARs/Exportieren mit in das jar kopiert wird? Öffne das Jar mal mit einen Unzip Programm!
 
Wie zur Hölle baust du deine Jar's zusammen, dass in der Jar irgendeine Zip Datei drin liegt, dann noch ein Ordner der wie die zip heißt, in dem Ordner eine Jar-Datei und ein Ordner, und alle gefühlt den gleichen Namen haben? 😵


Spontan würd ich sagen, an irgendeiner Stelle ist der Pfad falsch, erkennen kann ich da grad aber keinen Fehler.
Kannst du die zip (die exe darin ruhig gegen irgendeine txt-Datei austauschen) mal irgendwo hochladen?
 
Ahh, das ist auf jeden Fall nicht der Code, der dir vorgeschlagen wurde, du hast Install.class.getClass(), vorgeschlagen wurde nur getClass().

EDIT: Install.class ist in dem Fall das passende, das getClass() muss bei dir weg.
 
Da Du in einer static Methode bist, ist Install.class ohne das getClass() korrekt.

Das Lesen der Ressource wird vom ClassLoader gemacht. Daher brauchst Du den ClassLoader, der Deine Klasse geladen hat, denn der kann das jar File lesen.

Dadurch, dass Du die Klasse der Klasse (Also java.lang.Class) nutzt, landest Du aber bei einem anderen ClassLoader: Halt der von den eingebauten Klassen. Und die Ressource ist natürlich nicht Bestandteil des JDKs....
 
Ok, aber das geht dann nich, Cannot make a static reference to the non-static method getClass() from the type Object
Das Problem löst man allerdings nicht, indem man einfach irgendwas hinschreibt 😉

Lösung steht oben im edit; nur Install.class nutzen, also Install.class.getResourceAsStream. Nutzt du keine IDE? Meine warnt da direkt...
 

Zurück
Oben