# progress bar mit upload speed



## eskimo328 (30. Mai 2007)

Ich habe mir ein Applet gebastelt, mit welchem man Bilder uploaden kann.
Bisher aktualisiert sich meine Progress Bar nach jedem fertig hochgeladenen Bild.

Ich würde mir jedoch gerne anzeigen lassen mit welchem Speed (z.B. 45 kB/s) die Bilder hochgeladen werden.
Hat jemand ne Idee wie ich dies realisieren könnte?

Ich benutze folgende Variante für den Upload: http://forum.java.sun.com/thread.jspa?forumID=31&threadID=451245


----------



## MasterEvil (30. Mai 2007)

Du könntest einmal mit nen ProgressMonitor arbeiten, hab ich selbst einmal probiert, dabei hab ich aber irgendwas falsch gemacht und deswegen hats leider nicht so funktioniert wie ichs wollte deswegen hab ichs gleich wieder gelassen 
Mehr hier: http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html


Oder, so wie ichs eigentlich immer mache: Beim schreiben des Streams schreibst du immer nur X Bytes und in jedem Durchlauf aktualisierst du dann halt die Progressbar.
Also 1048576 Bytes (1MB) zu übertragen, dann immer 1024 Bytes schreiben. Der Progressbar-Status wird also auf Max 1048576 gesetzt und bei jedem Übertragen werden 1024 auf den aktuellen Status addiert.


----------



## Guest (30. Mai 2007)

Über den ProgressMonitor bzw. deine Lösung sehe ich aber auch keine Möglichkeit die Uploadgeschwindigkeit anzeigen zu lassen, oder verstehe ich deine Lösung nicht richtig?

Mein Ziel ist es anzeigen zu lassen, mit welcher Uploadgeschwindigkeit die Bilder aktuell zum Server übertragen werden. In etwa wie bei diesem Applet: www.javazoom.net/applets/jclientupload/demo/applet_http_efrontend.html


----------



## MasterEvil (30. Mai 2007)

Ahja, sorry hab wieder nur die Hälfte gelesen 

Da kann ich dir auch nicht weiter helfen aber das Tool sieht wirklich interessant aus! man könnte das JAR ja mal decompilieren und versuchen rauszufinden wie die das in etwa gelöst haben.

[Edit]
Oder guck mal ob dafür deren UploadBean nutzen kannst!


----------



## Ice-Tea (30. Mai 2007)

Angenommen es sind 1.000.000 Bytes zu übertragen (etwas unter ein MB)

1.000.000 / 1024 = 976,5625

Du braucht also 977 'einzelübertragungen'

Sindvoll wäre zu messen wie viele Übertragungen in einer, oder hochgerechnet 10 Sekunden passieren.

Dafür bräuchtest du einen Timer, der sich z.B. jede Sekunde das Bytearray ansieht.
Ich würde das so angehen (Pseudocode):



```
...
private int position; // um dem timer die chance zu geben sich das ganze anzusehen

private int[] bytes; //sollte 977 inhalte tragen (irgentwie muss es natürlich noch gefüllt werden) ;)
...
private void funktion(){
   for(int i=0;i<bytes.lenght;i++){
      this.position=i;
      ...
      bytes[i].senden();
   }
}
...
```

Sagen wir du hast 50x1024 Bytes in 1 Sekunden übertragen.

Das wären 51.200 Bytes - also 51,2KB die Sekunde 


Ich hoffe das hat geholfen


----------



## eskimo328 (30. Mai 2007)

das leuchtet mir ein. ich werde es so ausprobieren und dann berichten.


----------



## eskimo328 (1. Jun 2007)

mir stellt sich gerade ein weiteres problem, wenn ich ein bytearray an eine php-file schicke, wird daraus wieder mein bild erstellt. soweit kein problem.

jedoch wenn ich die bytes nicht im ganzen übertrage sondern einzeln, wie kann ich auf der php seite daraus wieder ein bild erstellen?


----------



## Ice-Tea (1. Jun 2007)

Hab mit php Streams noch nicht gearbeitet, aber so wie ich mich erinnere, musst du als daraus ein String erstellen und diesen dann speichern.


Bin mir da jetzt aber nicht sicher


----------



## eskimo328 (1. Jun 2007)

ich könte zwar eine file mit 1 MB in 900 übertragungen aufteilen.

d.h es wird 900 mal eine datei auf dem server aufgerufen und dieser daten geschickt. aber was stell ich mit den daten an?

hab schon versucht nach bei jeder übertragung die daten in einer file zu schreiben. und aus dieser file wieder mein image zusammen setzen. aber das dauert zu lange wenn 900 mal die file geöffnet und beschrieben werden muss.


----------



## masta // thomas (1. Jun 2007)

Buffer benutzen?


----------



## Guest (2. Jun 2007)

also eine Datei in mehrere Teile zu übertragen hat funktioniert jetzt muss ich noch schauen ob ich jede sekunde abfragen kann wie viel schon upgeloadet wurde.


----------



## madboy (2. Jun 2007)

Machs doch anders herum. Übertrage einen Teil und schaue, wie lange du dafür gebraucht hast.  Wird wohl einfacher sein.


----------



## eskimo328 (5. Jun 2007)

mein nächstes problem, wie kann ich schauen wie viel daten schon übertragen wurden?

bisher sieht meine struktur grob folgendermaßen aus:

1. File wird in ByteArray umgewandelt
2. Verbindung zu Zieladresse.php wird aufgebaut
3. Bild wird in mehrere Päckchen aufgeteilt
4. Päckchen (String) werden nacheinandern auf den DataOutputStream geschrieben


----------



## madboy (5. Jun 2007)

> mein nächstes problem, wie kann ich schauen wie viel daten schon übertragen wurden?


Mitzählen?
Jedes Mal wenn du ein "Päckchen" überträgst, erhöhst du einen Counter


----------



## eskimo328 (5. Jun 2007)

das problem is aber dass die päckchen hintereinander in einer schleife auf den DataOutputStream geschrieben werden. Man könnte jedes Päckchen auf den Stream schreiben, wenn das vorhergehende fertig übertragen ist, aber wie schau ich ob fertig übertragen wurde?


----------



## madboy (5. Jun 2007)

Während der Stream was schreibt, blockiert er meines Wissens, also die Methode write() schreibt fertig, dann erst gehts in deinem Programm weiter. Daher kannst du beruhigt mitzählen, während du in der Schleife den Stream befüllst.
Natürlich kann dir das Betriebssystem einen Strich durch die Rechnung machen, wenn es den Output puffert. Aber dagegen lässt sich nix machen (zumindest nicht so einfach).

Da fällt mir ein: schau mal DataOutputStream#size() an. Dann musst du nicht mal selber mitzählen.


----------



## eskimo328 (5. Jun 2007)

also wenn ich eine 300kB File an eine php-file schicke, wird nach nicht mal einer sekunde der DataOutputStream geschlossen und ers nach 30sekunden bekomm ich eine antowrt von der php-file.

also scheint es nicht so zu sein wie oben beschrieben?!?


----------



## madboy (5. Jun 2007)

eskimo328 hat gesagt.:
			
		

> und ers nach 30sekunden bekomm ich eine antowrt von der php-file.


 Das ist aber was anderes, als Daten weg zu schicken. Wenn du genau wissen willst, wann die Daten weg geschickt wurden, installiere dir einen Sniffer (wireshark z.B.) und schau da, wann die Daten dein System wirklich verlassen.

Das aber nur am Rande. Das eigentliche "Problem" sehe ich hier:



			
				eskimo328 hat gesagt.:
			
		

> also scheint es nicht so zu sein wie oben beschrieben?!?





			
				madboy hat gesagt.:
			
		

> Natürlich kann dir das Betriebssystem einen Strich durch die Rechnung machen, wenn es den Output puffert. Aber dagegen lässt sich nix machen (zumindest nicht so einfach).



Mit reinem Java sehe ich schwarz, wenn es wirklich daran liegt, dass das Betriebssystem puffert (was es bei Zugriffen auf Daten praktisch immer tut). Vor allem bei Netzwerkverbindungen und größeren Datenmengen sollte ein großer Unterschied bestehen zwischen dem Zeitpunkt, wann die Daten für dein Programm als "abgeschickt" gelten und dem Zeitpunkt, an dem die Daten wirklich auf dem Weg zur Gegenseite sind.

Obiges ist nur meine persönliche Meinung. Kann gut sein, dass ich mich irre :wink:


----------



## Fuxi (26. Jun 2007)

und wie siehts aus, meint ihr ich könnte mein problem lösen in dem ich die nicht per http sonder per ftp verschicke?


----------



## eskimo328 (28. Jun 2007)

hab jetzt enlich ne Lösung gefunden (per ftp), es funktioniert folgendermaßen:


```
//Connection zum remote host aufbauen
//...

//Timer starten
private void startTimer(){
	timer.schedule(new TimerTask(){
		public void run() {
			String speed = (counter-old)+"KBytes/s";
			old = counter;
			getFrame().getPanelBottom().getJStatusSpeed().setText(speed);
                                }
	}, 0, 1024);
}

//Image uploaden
private void transferImage(File f){
	OutputStream out;
	try {
		out = ftpclient.put(f.getName());
		InputStream in = new FileInputStream(f);
		byte c[] = new byte[1024];
		int read = 0;
		while ((read = in.read(c)) != -1 )
		{
			out.write(c, 0, read);
			counter++;
			bytesTransfered+=read;
		}
		in.close();
		out.close();
	} catch (IOException e) {
		e.printStackTrace();
	}

}
```


----------

