InputStream zu File kopieren - JPrograssbar anzeigen

GUI-Programmer

Top Contributor
Ich habe mir ein E-Mail Programm geschrieben. Mitlerweile ist es mir sogar gelungen Anhange runterzuladen. Dafür muss man sich den InputStream eines BodyParts holen und dann mit BufferedOutputStream und FileOutputStream den Datei erstellen. Das funktioiert soweit.
Nun muss man allerdings, bevor man eine JProgressBar mit setValue() Werten übergibt, bei dieser zuvor die maximale Größe einstellen. Jedoch weis ich nicht, wie man von InputStream den benötigten maximalen Wert bekommt.
So soll es in etwa werden:
Java:
public void downloadFile(final JProgressBar progress, final String filename, final int number) {
		SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
			BufferedOutputStream fos = null;
			BufferedInputStream is = null;

			@Override
			protected Void doInBackground() throws Exception {
				String userhome = System.getProperty("user.home");
				String separator = System.getProperty("file.separator");
				File file = new File(userhome+separator+"Downloads"+separator+filename);
				if(!file.exists()) file.createNewFile();
				
				is = inputstreams.get(number);
				fos = new BufferedOutputStream(new FileOutputStream(file));
				
				//progress.setMaximum(???);
				byte[] buffer = new byte[1024];
				int counter = 0;
				for (int length; (length = is.read(buffer)) != -1;) {
					fos.write(buffer, 0, length);
					counter++; 
					progress.setValue(counter);
				}
				return null;
			}
			
			@Override
			public void done() {
				System.out.println("Downloaded!");
				try {
					fos.flush();
					fos.close();
				}
				catch(Exception ex) {
					ex.printStackTrace();
				}
			}
		};
		worker.execute();
	}
Falls man nach der for-Schleife counter ausgibt, kommt ein anderer Wert raus, als durch irgendeine
Methode von den Inputsream is erreicht werden könnte!

Oder muss ich vieleicht anders vorgehen? - Evtl. schon vorher durch die message oder was anderes von javax.swing.mail die Größe des Anhangs ermitteln?

Vielen Dank für die Antworten!!! :)
 
G

Gast2

Gast
Du hast beim InputStream die Methode available(), die könnte dir helfen.

http://download.oracle.com/javase/7/docs/api/java/io/InputStream.html#available%28%29 hat gesagt.:
Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. A single read or skip of this many bytes will not block, but may read or skip fewer bytes.

Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.

A subclass' implementation of this method may choose to throw an IOException if this input stream has been closed by invoking the close() method.
 

bERt0r

Top Contributor
Nun ja ich bin jetzt nicht so vertraut mit dem POP3 Protokoll, aber iirc wird da irgendwo die Größe von Messages übertragen (evtl. auch von Anhängen?). Ansonsten könntest du dir noch die Java Mail API anschaun.
 

CroniD

Aktives Mitglied
Hmm gibt es denn ein "javax.swing.mail" Package? Ich glaube nicht. :)

Aber wenn es sich um E-Mails handelt, dann solltest du die Java Mail API bevorzugen, denn dort wird dir viel abgenommen. Eine, meiner Meinung nach, sehr gute Einführung findest du hier:
Die JavaMail API (Teil 1)
Die JavaMail API (Teil 2)
Die JavaMail API (Teil 3)
Die JavaMail API (Teil 4)

Also da wirst du wahrscheinlich auch Angaben finden wie Anzahl der Nachrichten, die auf dem Mail Account sind und wie groß so eine Nachricht dann ist. Vermute ich. Ich habe diese API bisher nur benutzt um Mails zu verschicken. Falls du auch das Versenden einer Mail visualisieren willst, dann kann ich dir da was fertiges geben. :)
 

CroniD

Aktives Mitglied
Habe mal selbst bisschen nach geschaut. ALso man erhält ja immer ein Folder Object. Von dem kann man auch den MessageCount abfragen. Eine Einzelne Message ist auch eine MimeMessage (nur bei der JavaMail API Refernzimplementierung). Auf diesem Object "MimeMessage" gibt es die getSize() Methode. Na ja ... die Javadoc sagt folgendes:
Code:
Return the size of the content of this message in bytes. Return -1 if the size cannot be determined.

Note that this number may not be an exact measure of the content size and may or may not account for any transfer encoding of the content.

This implementation returns the size of the content array (if not null), or, if contentStream is not null, and the available method returns a positive number, it returns that number as the size. Otherwise, it returns -1.
Das ist blöd. Man kann die Größe also erst abfragen, wenn die Nachricht komplett runter geladen ist. Ich kenne mich leider nicht genau mit POP3 und IMAP aus, aber vielleicht findet sich eine Größenangabe in den Headers, aber das kann mit unter Protokoll-spezifisch sein.
 

GUI-Programmer

Top Contributor
@CroniD: Die getSize()-Methode gibt mir allerdings einen größeren Wert, als dann letztlich der File groß ist, vermutlich, weil die MimeMessage auch noch Text, und mehrere Anhänge beinhaltet.

Es muss doch irgenwie gehen! Oder wie funktioniert denn sonst sonen Download bei Firefox (Ich weis natürlich das da nich Java verwendet wird!)
 
Zuletzt bearbeitet:

Atze

Top Contributor
manchmal ()wenn die messwerte fehlen bleibt wohl nix anderes übrig. allerdings sollte du eher großzügig rechnen, ein prozess der fertig ist bevor die progressbar durch ist macht imho mehr her als ein prozess der noch läuft wenn die progressbar auf 100% steht :)
 

CroniD

Aktives Mitglied
@CroniD: Die getSize()-Methode gibt mir allerdings einen größeren Wert, als dann letztlich der File groß ist, vermutlich, weil die MimeMessage auch noch Text, und mehrere Anhänge beinhaltet.

Es muss doch irgenwie gehen! Oder wie funktioniert denn sonst sonen Download bei Firefox (Ich weis natürlich das da nich Java verwendet wird!)

Ja, da liegt der Hase im Pfeffer! Wie ich bereits oben zitiert habe hängt der Rückgabewert von getSize() von dem jeweiligen internen Datencontainer der MimeMessage ab. Mit anderen Worten: Diese Zahl entspricht dem, was bereits für dieses Object runtergeladen (E-Mail empfangen) bzw. verschickt wurde (E-Mail verschicken). Außerdem kommen noch Protokoll-spezifische Eigenheiten hinzu.

D.h. im Prinzip wenn du beispielsweise eine neue MimeMessage anlegst mit Adressaten und Inhalt und Anhang usw., aber noch nicht verschickt hast (und auch nicht mittels Copy-Konstruktor in ein neues MimeMessage Object überführt hast), dann wird diese Methode wohl oder übel -1 zurückgeben, na ja, oder irgendwas anderes nicht korrektes. ^^ Sobald du die Mail verschickt hast und die ganzen Inhalte in Byteform übertragen wurden, steht auch die Size der Nachricht fest.

Deswegen sagte ich auch, dass du evtl. Glück haben könntest, ob im Header eine Größenangabe zu finden ist. Aber das ist wirklich ein Glücksfall, weil nicht jedes Protokoll sieht das vor und auch nicht jeder Mail Server setzt solche Angaben in den Header.

Jedenfalls ist das normal. Mein ThunderBird gibt mir beim herunterladen einer großen E-Mail auch keine exakte Statusanzeige. Wird mehr nach dem Prinzip "its done, when its done" visualisiert. Natürlich ... wenn du im Anhang eine Datei entdeckst, dann wird es dafür auch ein Object geben, von dem du die Größe erfragen kannst. Da, wie oben bereits beschrieben, ladet die JavaMail API nicht alles sofort vom Server, sondern nur das was du angefragt hast.

Also abstrakt beschrieben:
1. MimeMessage-Object erfragen
2. seinen Mime-Typ checken (multipart, siehe Die JavaMail API (Teil 3))
3. wenn multipart, dann über deren Teile iterieren und schaun ob Dateien dabei sind

Na ja, vielleicht darauf achten, dass du nicht die getContent() Methode benutzt, weil die ladet alles her unter.

Ach da fällt mir noch ein, dass es vor einiger Zeit mal einen Java E-Mail Client namens Columba (Columba (e-mail client) - Wikipedia, the free encyclopedia) gab. Vielleicht googlste danach mal, war ein Open Source Projekt, vielleicht findest du ja noch Quellcode irgendwo, aber ich glaube die haben kein JavaMail verwendet. :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Swing JEditorPane ohne Zeilenumbruch nach InputStream AWT, Swing, JavaFX & SWT 2
V Die Daten gehen verloren --> InputStream, ByteArrayInputS AWT, Swing, JavaFX & SWT 3
izoards JTable in CSV File schreiben... AWT, Swing, JavaFX & SWT 23
Ø Ein FXML-File mehrfach einfügen AWT, Swing, JavaFX & SWT 6
MiMa File Dateien im ListView als Name anzeigen? AWT, Swing, JavaFX & SWT 6
Rubberduck JavaFX Runnable jar file doesn't work AWT, Swing, JavaFX & SWT 2
F Output Stream / File Dateien / Speichern AWT, Swing, JavaFX & SWT 13
R FXML File kann nicht hinzugefügt werden! AWT, Swing, JavaFX & SWT 2
S JavaFX Variablen in einem FXML File verwenden AWT, Swing, JavaFX & SWT 8
B JavaFx TreeView mit file system AWT, Swing, JavaFX & SWT 1
J File Sucher AWT, Swing, JavaFX & SWT 4
L JavaFX TreeView mit File Objects AWT, Swing, JavaFX & SWT 0
D Swing JTable mit Inhalt aus XML-File AWT, Swing, JavaFX & SWT 3
Z JAVAFX Stage über Controller weitergeben um css-file zu laden AWT, Swing, JavaFX & SWT 4
M JFX8 Mixed 2D and 3D, Scene Subscene incorrect drawing 3ds-file AWT, Swing, JavaFX & SWT 6
R JavaFX Stage.close() funktioniert nicht im jar-File AWT, Swing, JavaFX & SWT 2
B JAXB , Unmarshal XML File AWT, Swing, JavaFX & SWT 3
T FileFilter: class File wird nicht gefunden AWT, Swing, JavaFX & SWT 2
Guybrush Threepwood Desktop.open(file) hängt AWT, Swing, JavaFX & SWT 4
J SWT jar-File relativ groß AWT, Swing, JavaFX & SWT 5
M JFreeChart in ein File schreiben (bzw. JFrame in ein File Schreiben) AWT, Swing, JavaFX & SWT 2
C File-Objekte an JList übergeben und abrufen AWT, Swing, JavaFX & SWT 6
Z Component für File-Browser ähnliche Oberfläche AWT, Swing, JavaFX & SWT 6
T SWT Window Builder Pro File Dialog anzeigen AWT, Swing, JavaFX & SWT 10
Z Swing Mittels GUI Werte aus Property-File ändern AWT, Swing, JavaFX & SWT 5
S JTree aus List<File> erstellen AWT, Swing, JavaFX & SWT 8
L Filechooser File Öffnen AWT, Swing, JavaFX & SWT 4
I Swing JTree aus ArrayList<File> erzeugen AWT, Swing, JavaFX & SWT 15
E Swing File lesen und in JEditorpane AWT, Swing, JavaFX & SWT 2
N File.setlastmodified() AWT, Swing, JavaFX & SWT 5
J Progressbar aktualisierung nach file übergabe AWT, Swing, JavaFX & SWT 7
T Dynamic JTree: File System Problem AWT, Swing, JavaFX & SWT 2
freakysheep mit jtree config file erzeugen AWT, Swing, JavaFX & SWT 2
M File-Chooser Problem (2 X Mausklick öffnen) AWT, Swing, JavaFX & SWT 11
N JFilechooser File auslesen AWT, Swing, JavaFX & SWT 10
R Jar File AWT, Swing, JavaFX & SWT 2
M File.listFiles() mit dem FileFilter von JFileChooser? AWT, Swing, JavaFX & SWT 14
I Dateiendung aus File AWT, Swing, JavaFX & SWT 9
A Probleme mit einer JOptionPane in einem jar-File AWT, Swing, JavaFX & SWT 14
G avi-Datei mit Desktop.getDesktop().open(File) öffnen AWT, Swing, JavaFX & SWT 4
DeeDee0815 JEditorPane + HTML + <img src=file> + JAR = FALSE AWT, Swing, JavaFX & SWT 3
E GUI-Elemente aus txt- oder xml-File erstellen? AWT, Swing, JavaFX & SWT 5
F File Chooser - nur PDFs AWT, Swing, JavaFX & SWT 2
C File Explorer simulieren AWT, Swing, JavaFX & SWT 6
B Problem mit ImageIcons in einem Jar-File AWT, Swing, JavaFX & SWT 7
M Windows file icons in Java verwenden AWT, Swing, JavaFX & SWT 2
N JFileChooser => Exc. in thread "Basic L&F File L AWT, Swing, JavaFX & SWT 11
P SkinLF aus jar-File AWT, Swing, JavaFX & SWT 5
C getIcon für ein File das es nicht gibt? AWT, Swing, JavaFX & SWT 2
U externes .jar file einbinden [jdic] AWT, Swing, JavaFX & SWT 16
Z jar-File mit SWT - Exception AWT, Swing, JavaFX & SWT 4
M Ausführbares Jar File AWT, Swing, JavaFX & SWT 12
N File von HDD in JEditorPane laden? AWT, Swing, JavaFX & SWT 2
V SWT Programm als jar-File starten AWT, Swing, JavaFX & SWT 5
P XML-File in Java-App darstellen - wie im Internet Explorer AWT, Swing, JavaFX & SWT 2
D File verschieben. In java möglich? AWT, Swing, JavaFX & SWT 3
J ganz dringend File Chooser: extensions! AWT, Swing, JavaFX & SWT 6
M Java Dateien kopieren mit Fortschrittsbalken AWT, Swing, JavaFX & SWT 13
izoards Ordner Rekursiv kopieren - Fortschritt? AWT, Swing, JavaFX & SWT 5
E JLabel kopieren AWT, Swing, JavaFX & SWT 31
VPChief Gibt es eine möglichkeit Dateien aus der jar datei zu kopieren? AWT, Swing, JavaFX & SWT 46
J SWT Textfeld markieren und kopieren AWT, Swing, JavaFX & SWT 0
F JavaFX textField Ausgabe automatisch kopieren AWT, Swing, JavaFX & SWT 7
L Image in anderes kopieren AWT, Swing, JavaFX & SWT 0
S Swing Style Attribute aus JTextPane kopieren AWT, Swing, JavaFX & SWT 1
S Swing Kopieren einer vollständigen Zeile einer JTable AWT, Swing, JavaFX & SWT 3
F Bilder ineinander kopieren AWT, Swing, JavaFX & SWT 3
D Schnelles kopieren von Pixeln in ein BufferedImage AWT, Swing, JavaFX & SWT 25
S Bilddatei kopieren, aber ohne verluste und ohne zu großen Speicherverbrauch AWT, Swing, JavaFX & SWT 17
D Applet FTP Ordner kopieren AWT, Swing, JavaFX & SWT 3
P Objekt kopieren AWT, Swing, JavaFX & SWT 2
S Dateien kopieren mit ProgressBar AWT, Swing, JavaFX & SWT 6
Landei Swing JTable - Tabellenzeile kopieren AWT, Swing, JavaFX & SWT 2
Daniel_L jEditorPane - Formatierten Text in Zwischenablage kopieren? AWT, Swing, JavaFX & SWT 2
S Inhalt einer JTable kopieren? (GlazedLists) AWT, Swing, JavaFX & SWT 2
H explorer in java - datein kopieren AWT, Swing, JavaFX & SWT 5
M JPanel Inhalt kopieren AWT, Swing, JavaFX & SWT 5
G AbstractTableModel kopieren AWT, Swing, JavaFX & SWT 4
O Panel "kopieren" ? AWT, Swing, JavaFX & SWT 6
H JTable Text aus mehreren Zellen in einer Spalte kopieren? AWT, Swing, JavaFX & SWT 3
E SWT: Tabellen-Inhalt kopieren AWT, Swing, JavaFX & SWT 2
T BufferedImage kopieren AWT, Swing, JavaFX & SWT 3
D Inhalt eines JPanel kopieren AWT, Swing, JavaFX & SWT 7
A Kopieren aus JTextArea nicht zulassen AWT, Swing, JavaFX & SWT 6
R Kopieren in Java AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben