# upload progress bei einem http file post



## eisenhauer (12. Jul 2007)

hallo!

ich habe das problem dass ich über einen http post eine datei hochladen möchte. also:


```
URLConnection conn = new URLConnection(new URL(...));	
  DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
		
(...)

  FileInputStream fis = new FileInputStream(file);
  byte[] bytes = new byte[(int)file.length()];
  fis.read(bytes);
  dos.write(bytes);

(...)
	
  dos.flush ();
  dos.close ();
```

soweit klappt auch alles wunderbar. jetzt möchte ich aber den fortschritt des datei uploads bekommen. der findet aber erst stattt nachdem der outputstream geschlossen ist. kann ich irgendwie auf diese aktivitäten der urlconnection zugreifen?

bin für jede idee dankbar..

schöne grüße
lukas


----------



## tuxedo (12. Jul 2007)

Werden die Daten erst beim flush() übertragen? Dachte das läuft schon beim dos.write() ... 

Im Fall von dos.write() kannst du ja vorher ermitteln wieviel Bytes die gesamte Datei hat. Und in der while-schleife beim füttern des Streams kannst du dann mitzählen wieviel schon geschrieben wurde ...


----------



## eisenhauer (13. Jul 2007)

hi! erstmal danke für die antwort!

also das problem ist dass die daten über den dataoutputstream in den puffer geschrieben werden aus dem sie dann schließlich versendet werden. das heißt wenn ich dos.flush() mache schreibt er die datei zwar komplett in den "ausgangs"-puffer aber an den wirklichen prozess des http posts komm ich nicht ran.

im moment bin ich von der urlconnection ab, weil die wohl in ihren fähigkeiten ziemlich begrenzt zu sein scheint. ich probier es gerade mit dem HttpClient aus dem jakarta commens projekt. über den outputstream der klasse HttpConnection müsste ich doch da irgendwie an informationen kommen wieviel schon geschickt wurde. aber ich weiß leider noch nicht wie ich den richtigen outputstream erwische. also im moment sieht es so aus:


```
public void postFile(String name, File file) throws Exception
{		
	PostMethod post = new PostMethod("http://www.os.staybeta.de/lukastest/lukastest.php");
	Part[] parts = {new FilePart("file", file)};
	post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
		
	HttpClient client = new HttpClient();
	HttpConnectionManager manager = client.getHttpConnectionManager();
	HttpConnection conn = manager.getConnection(client.getHostConfiguration());
	FileOutputStream fos = (FileOutputStream)conn.getRequestOutputStream();
	final FileChannel channel = fos.getChannel();
(...)
```

über den FileChannel will ich dann mit channel.position() an die aktuelle position im stream kommen. leider krieg ich beim compilen immer den fehler:

java.lang.IllegalArgumentException: host parameter is null
	at org.apache.commons.httpclient.HttpConnection.<init>(HttpConnection.java:206)
	at org.apache.commons.httpclient.HttpConnection.<init>(HttpConnection.java:155)
	at org.apache.commons.httpclient.SimpleHttpConnectionManager.getConnectionWithTimeout(SimpleHttpConnectionManager.java:175)
	at org.apache.commons.httpclient.SimpleHttpConnectionManager.getConnection(SimpleHttpConnectionManager.java:217)
	at org.apache.commons.httpclient.SimpleHttpConnectionManager.getConnection(SimpleHttpConnectionManager.java:129)
	at HttpDataPoster.postFile(HttpDataPoster.java:147)
	at HttpDataPoster.main(HttpDataPoster.java:235)


hat jemand ne idee wie ich an einen gültigen outputstream kommen kann? oder wie ich das sonst realisieren soll?

bin für jede anregung dankbar!

gruß
lukas


----------



## brdietdidi (24. Jul 2007)

Hi,

ich habe das gleiche Problem und rätsle schon seit ein paar Tagen, wie das wohl zu machen wäre. Ich verwende auch den jakarta.commons.HttpClient.

Was ich mich abere auch frage: Was soll die Progress-Bar eigentlich anzeigen? In diesem Fall doch nicht nur die Übertragungszeit, sondern das Upload als gesamtes. Also auch den Fortschritt des Schreibens auf dem Server. In diesem Fall braucht man aber wahrscheinlich eine Server-Komponenten, die permanent die Fortschritt zurückschickt. Wie fängt man sowas mit einer Post-Methode ab? Das geht doch wohl nicht...

Aber irgendwie muß es ja gehen, da es ja auf dem Markt schon einige Progress-Bars gibt.

Bin auch dankbar für jede Anregung.


----------



## brdietdidi (6. Aug 2007)

Ich habe mein Problem folgend gelöst. Ist vielleicht nicht ganz das, was man sich vorstellt (da das tatsächliche Schreiben auf dem Server dadurch nicht widergespiegelt wird), jedoch ist es mehr als gar nix.

Da ich einen MultiPart-Post anstrebe (weil ich mehrere Files _zugleich_ uploaden will), habe ich die Methode _sendData(OutputStream)_ der Klasse _org.apache.commons.httpclient.methods.multipart.FilePart_ um die Benachrichtigung eines _ProgressListeners _erweitert:


```
protected void sendData(OutputStream out) throws IOException
  {

   [...]

    byte[] tmp = new byte[4096];
    InputStream instream = getSource().createInputStream();
    try
    {
      int len;
      while ((len = instream.read(tmp)) >= 0)
      {
        out.write(tmp, 0, len);




        if (progressListener != null)
          progressListener.bytesWritten((double)len / 1000.00); // weil meine Implementierung des Listeners in KB arbeitet





     }
    }
    finally
    {
      // we're done with the stream, close it
      instream.close();
    }
  }
```

P.S.: Der _ProgressListener _ist ein frei erfundenes Interface, das bei der Instantiierung meiner FilePart-Klasse mitgegeben wird.


----------



## Dante (17. Aug 2007)

hi, 

das schreiben auf dem server bekommst du eh nicht mit. Warscheinlich sieht java eh nur die ANzahl von Bytes die unten aus der virtuellen Maschine rausfallen und in den TCP-Buffer gehen. Der schickt die dann irgendwann raus und so Gott will, kommen die auch an und so Gott nochmal will, kommt die Bestätigung auch wieder bei uns an.

Dann weiss unser Betriebssystem dass es wieder ein Paket absenden darf, das heisst es ist dann wieder etwas Platz im Buffer, was java auch mitbekommt, wieder etwas reintut und dir das dann auch deutlich macht. Das heisst du bist maximal ungenau um die Größe des TCP-Send-Window und ein paar Buffern auf dem Weg zur Netzwerkkarte. Die sollten aber so riesig nicht sein.


----------

