2017-05-21 3 views
6

Also meine Aufgabe ist es, ein kleines Programm zu erstellen, das eine Liste von Mediendateien anzeigt und diese Mediendateien separat mit Standard-OS-Medienplayer ausführen.Korrekte Verpackung von runnable Jar-Projekt in Netbeans

Meine aktuelle Lösung ein Paket zu erstellen war, das alle Mediendateien hält, so etwas wie:

-com.media 
     |_a.mp4 
     |_b.mp4 

den folgenden Code Kopien in ein temporäres Verzeichnis der ausgewählten mp4, läuft dann die Standard-os-Media-Player:

public File copyTempMedia(File tempAppFolder, String videoName) { 

    URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName)); 
    File from = new File(f.getPath()); 
    File to = new File(tempAppFolder.getAbsolutePath()); 

    try { 
     FileUtils.copyFileToDirectory(from, to); 
    } catch (IOException ex) { 
     Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    System.out.println("Temp video copied: " + to.getAbsolutePath() + "/" + to.getName()); 
    return to; 
} 

public void triggerMediaPlayer(String fileLocation) { 
    System.out.println("Triggering media player: " + fileLocation); 
    try { 
     if (OPERATIN_SYSTEM.contains("Linux")) { 
      Runtime.getRuntime().exec("sh -c " + fileLocation); 
     } else if (OPERATIN_SYSTEM.contains("Windows")) { 

      Runtime.getRuntime().exec("cmd /c " + fileLocation); 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(MediGUIModel.class.getName()).log(Level.SEVERE, null, ex); 
     ex.printStackTrace(); 
    } 
} 

wenn ich das Programm durch Netbeans führen sie es als espected funktioniert, aber wenn ich einen clean/build den Lauf machen die .jar aus dem Build erstellt, die Mediendatei scheint nicht gelesen zu werden, so meine Fragen sind:

  1. Warum funktioniert es durch Netbeans und nicht durch Build .jar?
  2. Ist dies die beste Lösung für dieses Problem?
  3. Sollte ich die Medien anders verpacken?

Vielen Dank im Voraus.

bearbeiten

So, nachdem statt Doppelklick jar durch Konsole ausgeführt wird, ist eine Null-Zeiger-Ausnahme in der Zeile, wo ich die Datei lesen:

URL f = getClass().getResource(String.format("%s/%s", Constants.MEDIA_LOCATION, videoName)); 

Warum es in Netebeans funktioniert aber nicht auf Build/Glas?

Gibt es einen anderen Ort im Jar, in dem ich die Mediendateien platzieren könnte, so dass sie ohne Probleme durch getResource oder getResourceAsStream gelesen werden?

Antwort

3

Wenn Sie das Projekt in NetBeans ausführen, wird das ausführbare Jar wie java -jar yourproject.jar nicht ausgeführt. Stattdessen wird der Klassenpfad so eingestellt, dass Klassen/Klassen wie java -cp build/classes com.media.YourMainClass erstellt werden. Das bedeutet, dass Ihre Videodateien tatsächliche Dateien sind, die sich in Ihrem Projekt/build/classes/com/media befinden. Sie können auf normale Dateien im Dateisystem zugreifen und wie eine normale Datei kopiert werden. Wenn Sie vom Jar aus starten, werden die Dateien in der JAR-Datei gepackt und können nicht mit einfachen Dateikopierbefehlen kopiert werden.

Anstatt die URL durch den Aufruf getClass().getResource() zu erhalten, versuchen Sie, InputStream telefonisch getClass().getResourceAsStream(). Sie können dann eine einfache Schleife schreiben, um die Bytes aus dem Eingabestream in Ihre temporäre Datei zu kopieren.

+0

Hey Corey, habe ich versucht mit 'getResourceAsStream', aber das gibt nur null zurück. Irgendwelche anderen Vorschläge? – shep

+0

Gibt es noch einen anderen Platz im Jar, in dem ich die Mediendateien platzieren kann, damit sie problemlos mit 'getResource' oder' getResourceAsStream' gelesen werden können? – shep

+0

Sie erhalten eine Null, weil der Pfad nicht ganz richtig ist. Fügen Sie beispielsweise einen führenden Schrägstrich "/com/media/a.mp4" hinzu. – Corey

1

Ok, so fand ich eine Lösung:

  1. Erstellen Sie ein separates Projekt mit media.*.mp4.
  2. Exportieren als Jar Bibliothek.
  3. Importieren Sie die Bibliothek in die Desktop-App.
  4. Stellen Sie sicher, dass sich die Bibliothek im Klassenpfad befindet.

Diese Lösung funktioniert für mich ...

Wenn jemand eine bessere Lösung hat, glücklich zu hören, hoffentlich bevor Prämie ist bis :)

2

Dieser Ausschnitt kann hilfreich sein:

BufferedInputStream result = (BufferedInputStream) getClass().getResourceAsStream("/com/media/a.mp4"); 
    byte[] bytes = new byte[4098]; 
    try { 
     result.read(bytes); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    System.out.println(new String(bytes)); 

Sie werden die Bytes in einer Schleife lesen müssen oder etwas, aber das sollte funktionieren, ohne ein separates Glas zu benötigen.

2

Ich denke, es ist keine gute Idee, Ihre Mediendateien in das Glas zu legen, weil Sie das Projekt neu erstellen müssen, wenn Sie eines ändern möchten und die Glasgröße wächst.

Verwendung:

File from = new File(String.format("%s/%s", Constants.MEDIA_LOCATION,videoName)); 

Um Ihre Dateien aus dem gleichen Ordner wie das Glas zu laden.

Wenn Sie die Medien im Jar behalten möchten, erstellen Sie ein Maven-Projekt und legen Sie das MP4 in src/main/resources ab. Verwenden Sie Maven, um ein Fettglas zu erstellen, und die Ressourcen src/main/resources werden in das Glas eingeschlossen. Siehe 'maven-shade-plugin' zum Konfigurieren der pom.xml und https://www.mkyong.com/maven/create-a-fat-jar-file-maven-shade-plugin/

Dann können Sie die anderen Eigenschaften der anderen Maven verwenden!

Siehe Reading a resource file from within jar

bearbeiten

Nach einigen Versuchen, ich es nicht richtig mit 'getResource' aus dem Glas bekommen. Der Pfad, den Sie aus dem Jar erhalten, ist wie folgt: file:/C:/.../JavaApplication4/dist/JavaApplication4.jar!/test.txt und nicht als gültiger Dateisystempfad erkannt.

Sie können 'getResourceAsStream' verwenden und die Datei aus dem Jar in den lokalen Ordner kopieren.

InputStream in; 
OutputStream out; 
IOUtils.copy(in,out); 
in.close(); 
out.close();