Programm, dass Multipart RARs entpackt

onkelbonus

Cadet 4th Year
Registriert
Aug. 2006
Beiträge
82
Hallo zusammen,

ich möchte gerne ein Programm schreiben, dass Multipart RAR Archive entpacken kann, und automatisch weiterentpackt, sobald der nächste Part im entsprechenden Ordner zugefügt wird. D.h. man fängt an zu entpacken, ohne bereits das vollständige Archiv zu haben, während weitere Parts z.B. noch runtergeladen werden.

Ich habe bisher nur Java Kenntnisse, habe auch bisschen was in C++ geschrieben, aber mit ein bisschen Einarbeiten sollte das auch gehen. Zunächst war meine Idee eine Bibliothek zu benutzen, die mit Rar umgehen kann, aber ich hab da keine passende API gefunden, die entsprechende Features hat (oder ich hab die API nicht verstanden) . Dann wollt ich einfach die unrar.exe nutzen von Winrar nutzen.
Manuell über die CMD, sieht das so aus:


Code:
C:\downloads/unrar.exe e -vp test.part1.rar

UNRAR 4.00 freeware      Copyright (c) 1993-2011 Alexander Roshal


Extracting from test.part1.rar

Extracting  test1.dat                                   OK
Extracting  test2.dat
Insert disk with test.part2.rar [C]ontinue, [Q]uit

Das Programm sollte dieses Output auslesen können, und sobald die passende Datei im Ordner auftaucht, sollte es in den InputStream einfach "C" für Continue schreiben.
Das klingt irgendwie einfach, jedoch kann mein Programm dieses Output nicht auslesen. Das Programm sieht so aus:

Code:
public static void main(String argv[]) {
    try {
      String line;
      Process p = Runtime.getRuntime().exec
        ("C:/downloads/unrar.exe e -vp C:/downloads/test.part1.rar");
      BufferedReader input =
        new BufferedReader
          (new InputStreamReader(p.getErrorStream()));
      while ((line = input.readLine()) != null) {
       line = input.readLine();
        System.out.println(line);
      }
      input.close();
    }
    catch (Exception err) {
      err.printStackTrace();
    }
  }

Weder p.getInputStream noch p.getErrorStream liefern mir die "InsertDisk" Nachricht, bei p.getInputStream kommt nur das hier raus:
Code:
UNRAR 4.00 freeware      Copyright (c) 1993-2011 Alexander Roshal
p.getErrorStream liefert garnichts, stattdessen bleibt das Programm in beiden Fällen in einer Endloschleife hängen, was wohl daran liegt, dass unrar.exe auf eine Eingabe wartet, da der nächste Part fehlt.

Kann mir jemand da vielleicht weiterhelfen? Ich komme da nicht weiter...
 
Hm, ich will dich jetzt nicht entmutigen, aber WinRAR macht das schon von selbst.

Wenn ich auf Datei.rar.part01 klicke, macht er danach direkt mit Datei.rar.part02 usw weiter...
 
Es geht aber darum, dass der nächste Teil noch nicht fertig ist. Das Programm soll dann warten, bis der nächste Teil vollständig da ist und erst dann weiter entpacken.
 
Ich glaube du willst die Dateien entpacken, ohne bereits alle zu haben... das ist zwar eine spannende Idee, aber das Problem ist die Durchführung. Du brauchst eine gehörige Menge Rechenleistung und Speicher dafür, da du sämtliche Informationen cachen musst, eine Konsistenzprüfung brauchst und dann noch eine automatische Wartefunktion, die abhört, ob die nächste Datei bereit steht... ganz ehrlich? Das lohnt der Mühe nicht...
Mit Java ist so etwas wohl auch nicht machbar oder zumindest nicht leicht... ich denke, du brauchst dafür unter Windows wohl eine .Net-Umgebung.
 
Warum addierst nicht ne variable, die ne for to do schleife durchläuft (anzahl der multiarchive)
so in etwa:

("C:/downloads/unrar.exe e -vp C:/downloads/test.part.rar");
das ganze halt bis max. archive durchlaufen wurden
 
Also Winrar GUI stoppt mit einem Dialogfeld und fragt nach dem nächsten Teil. Auch die Kommandozeilenversion wird vermutlich hier stoppen und auf eine Eingabe warten.
 
Rome1981 schrieb:
Ich glaube du willst die Dateien entpacken, ohne bereits alle zu haben... das ist zwar eine spannende Idee, aber das Problem ist die Durchführung. Du brauchst eine gehörige Menge Rechenleistung und Speicher dafür, da du sämtliche Informationen cachen musst, eine Konsistenzprüfung brauchst und dann noch eine automatische Wartefunktion, die abhört, ob die nächste Datei bereit steht... ganz ehrlich? Das lohnt der Mühe nicht...
Mit Java ist so etwas wohl auch nicht machbar oder zumindest nicht leicht... ich denke, du brauchst dafür unter Windows wohl eine .Net-Umgebung.

Aber das managed doch alles die Unrar.exe, ich muss der doch nur sagen, wann sie weitermachen soll, nachdem sie pausiert hat. Mein Programm müsste also lediglich ein Verzeichnis abhören, ich denke, dass ich das hinkriege. Mein Problem ist wie gesagt, zu erkennen, wann die unrar.exe wartet.

Sturm91 schrieb:
Warum addierst nicht ne variable, die ne for to do schleife durchläuft (anzahl der multiarchive)
so in etwa:

("C:/downloads/unrar.exe e -vp C:/downloads/test.part.rar");
das ganze halt bis max. archive durchlaufen wurden

So funktioniert das nicht, was wahrscheinlich funktionieren würde, ist einfach den Continue befehl in einer Endlosschleife in den InputStream des Prozesses zu schreiben, das wäre halt die unschöne Variante, wenn ich nicht rausfinde, wie es sonst geht, probier ich das mal.
 
Zuletzt bearbeitet:
Weil das in einen Fehler laufen würde und zu einem Abbruch oder einer Endlosschliefe führt?
Es muss eine Wartefunktion mit Listener rein und das macht man nicht mit einer Schleife...
 
@makiyt: Ich glaube er meint, das Programm soll warten, bis die entsprechende Datei vorhanden ist (z.B. vollständig heruntergeladen), da ansonsten ja (zumindest bei 7-zip) ein Prfsummenfehler kommt und die Datei logischerweise nur soweit entpackt ist, wie Daten vorhanden sind.
D.h. das Programm entpackt nicht automatisch weiter, wenn der nächste Teil bereitliegt.

@topic: ich weiß nicht, wofür du das benötigst, aber würde es nicht auch reichen, einfach immer mal wieder das Archiv zu entpacken, das dann ja jedesmal soweit entpackt wird, wie Daten vorhanden sind.
Bei deiner angestrebten Lösung würde ja auch stetig Schreibzugriff von deinem Programm ausgeübt, oder?

Korrigier' mich, falls ich was falsch verstanden habe.
 
simpsonsfan schrieb:
@makiyt: Ich glaube er meint, das Programm soll warten, bis die entsprechende Datei vorhanden ist (z.B. vollständig heruntergeladen), da ansonsten ja (zumindest bei 7-zip) ein Prfsummenfehler kommt und die Datei logischerweise nur soweit entpackt ist, wie Daten vorhanden sind.
D.h. das Programm entpackt nicht automatisch weiter, wenn der nächste Teil bereitliegt.

@topic: ich weiß nicht, wofür du das benötigst, aber würde es nicht auch reichen, einfach immer mal wieder das Archiv zu entpacken, das dann ja jedesmal soweit entpackt wird, wie Daten vorhanden sind.
Bei deiner angestrebten Lösung würde ja auch stetig Schreibzugriff von deinem Programm ausgeübt, oder?

Korrigier' mich, falls ich was falsch verstanden habe.

Ok ich erklär nochmal wie ich es meine:

  1. Das Programm startet den Entpackvorgang.
  2. Der Entpackvorgang stoppt irgendwo. Unrar.exe liefert die Meldung "Insert disk with xxxxx.partx.rar [C]ontinue, [Q]uit"
  3. Das Programm erkennt, die Meldung, und fängt an, das Verzeichnis zu überwachen. Sobald xxxxx.partx.rar in dem Verzeichnis auftaucht, wird mit Hilfe von p.getOutputStream() in den InputStream des Prozesses p der String "C" geschrieben.
  4. Wieder bei 2 Anfangen, bis fertig.

Knackpunkt ist hierbei, zu erkennen, wann unrar.exe wartet. Eigentlich sollte die doch in irgendwelche Streams alles was die so von sich gibt reinschreiben, aber ich finde das eher in p.getInputStream noch in p.getErrorStream. Habe ich was falsch gemacht, ist das eine Limitierung von Java, oder liefert unrar mir einfach nicht diese gefragte Information?

Alternativ die "Brute Force Methode", falls mir keiner sagen kann, wie ichs so wie oben beschrieben machen könnte:

  1. Das Programm startet den Entpackvorgang.
  2. Das Programm schreibt in den InputStream des Prozesses, der unrar ausführt, solange "C" rein, bis der Entpackvorgang abgeschlossen ist
 
Zuletzt bearbeitet:
Hi onkelbonus,
was ich so interessant finde, ist, dass du in deinem Beispielcode aus dem Startpost die Methoden getInputStream und getErrorStream verwendest. Klar das beide nicht zum Lesen der Ausgabe geeignet sind, weil:

InputStream: Eingabestream, d.h. alles was du in diesen Stream schreibst wird an das Programm weitergegeben, hier also einfach den Buchstaben "C" für Continue reinschreiben. Der Zugriff auf diesen Stream ist schreibend nicht lesend.

ErrorStream: Im Fehlerfall schreiben meist Programme die Fehlermeldung in diesen Stream rein, d.h. du greifst lesend darauf zu und kannst so Fehlermeldungen auswerten. Aber die Meldung die du im Fenster siehst ist kein Fehler sondern nur ganz normaler Output.

OutputStream: hier sollte das zu finden sein, was du suchst, nämlich die ganz normale Nachricht, das du die nächste Datei bereitstelllen sollst um dann mit "C" wieder weitermachen zu können.

Also schau einfach mal ob du ein getOutputStream in der Process Klasse hast und verwende das für deine Auswertungen. Ach noch etwas. Wenn du lesend auf Output und Error Stream zugreifst, dann wird vorraussichtlich deine App solange blockiert bis tatsächlich was gelesen werden konnte. Also schau mal bei der Stream Klasse ob du mit irgendetwas wie z.B. "Peek", "Count", "EOL", "EOF" oder ähnlichem vor dem Lesen prüfen kannst ob tatsächlich Daten vorhanden sind, die gelesen werden können.
 
Zuletzt bearbeitet:
Ich denke du hast da was falsch Verstanden, ein InputStream in Java ist zum lesen gedacht, der hat auch nur read() Methoden. Der p.getInputStream liefert das Output des Prozesses. Mit p.getOutputStream kann man in das Input des Prozesses schreiben. Ist vielleicht etwas verwirrend^^.
 
der jdownloader (java basierter downloader manager) kann das,
weil er opensource ist, köntest du einfach schauen wie es dort gelöst ist.
 
die erkennung läuft aber dynamisch,
sprich wenn mehrere download in einem auftrag drin sind erkennt er die einzelen und
entpackt so balt es geht.
 
Das wäre mir neu. Also bei mir fängt der den Entpackvorgang auch bei multipart Archiven erst an, wenn alle vorhanden sind.
 
Na das war ja mal nen voller Griff ins Klo von mir! :D

Wie dem auch sei, sehe es gibt eine Methode"int InputStream.available()", Mit der kannst du zumindest schon mal prüfen ob es überhaupt was gibt zum Lesen. Warte einfach solange bis du tatsächlich Daten drin hast, die auch gelesen werden können oder besser du machst in der Zwischenzeit anderen Kram, der nicht abhängig davon ist...

Vielleicht wirst du hier fündig: http://sourceforge.net/projects/jrar/
 
Zurück
Oben