Progress bei ObjectOutputStream?!

mccae

Senfdazugeber
Grüße!

Folgende Situation:

1 Datei. Diese ist nie größer als 1Mb und wird wird geladen.
Das ganze ist ein serialisierbares Objekt mit einem byte array.

Der Kollege wird an einen Sendethread übergeben, der einen ObjectOutputStream mit dem Ouputstream eines Sockets verkettet hat.

Dieser Thread sendet über writeObject(Object o); des ObjectOutputStreams das Objekt an den Server der damit rumspielt.

So,..

Gibt es jetzt eine Möglichkeit den Progress der Methode writeObject abzufragen?
Ich möchte nämlich den Progress an ein GUI weitergeben,...

Ich hab das ganze relativ simpel gestaltet. Eine TCP Verbindung, und ein Thread welcher die Objekte losschickt. Auf der anderen Seite der Server der je nach Objekt das hereinkommt reagiert,...
Meine Programmier-lehrerin würde mir nämlich auf die Finger hauen und sagen ich solle bei Dateiübertragungen gefälligst Datagram zeugs benutzen,...

Also,.. Gibt es eine Möglichkeit den Progress zu erfahren?
 
Unter den 24 Leuten die den Post gelesen haben wird doch ein wissender sein?!

Mach ich etwa irgendetwas falsch?
 
Hallo,

AW: Progress bei ObjectOutputStream?!
Unter den 24 Leuten die den Post gelesen haben wird doch ein wissender sein?!

Mach ich etwa irgendetwas falsch?
Immer schön langsam... wer nett und höfflich bleibt bekommt auch eine passende Antwort...

zur Inspiration...
http://www.tutorials.de/forum/swing-java2d-3d-swt-jface/196528-ordner-kopieren-mit-jprogressbar.html

For ObjectOutputStream Progress Tracking...

Leite von ObjectOutputStream ab (ProgressAwareObjectOutputStream extends ObjectOutputStream) setze die Anzahl der zu schreibenden bytes an (entweder korrekt oder geschätzt) überschreibe die write(int) bzw. write(byte[])... und zähle darin die durchgeflossenen bytes und rufe die entsprechende super-Methode auf (super.write(int));


Gruß Tom
 
Hallo,


Immer schön langsam... wer nett und höfflich bleibt bekommt auch eine passende Antwort...

zur Inspiration...
http://www.tutorials.de/forum/swing-java2d-3d-swt-jface/196528-ordner-kopieren-mit-jprogressbar.html

For ObjectOutputStream Progress Tracking...

Leite von ObjectOutputStream ab (ProgressAwareObjectOutputStream extends ObjectOutputStream) setze die Anzahl der zu schreibenden bytes an (entweder korrekt oder geschätzt) überschreibe die write(int) bzw. write(byte[])... und zähle darin die durchgeflossenen bytes und rufe die entsprechende super-Methode auf (super.write(int));


Gruß Tom

Huhu,

Wie du weißt, Zeit ist Geld und ich habe beides nicht :D

Die meiste Zeit habe ich dieses Forum nur gelesen und soweit ich weiß bist du so etwas wie ein Java Gott?!

Wie auch immer,..
Vielen Dank für deine Antwort!

Die Applikation auf der anderen Seite der Leitung hat nur eine while(true) schleife in der nur objects gelesen werden mit readObject(). Je nach Objekt wird dann reagiert,...

Wenn ich jetzt writeObject(Object o) überschreiben will, wie zähle ich die bytes?
Woher weiß ich wie writeObject(Object o) genau funktioniert?

Denn wenn ich super.writeObject(Object o) aufrufe wird das Objekt ja schon in den Stream geschrieben,...
Wie kann ich da die bytes zählen?

Ein serialisiertes Objekt besteht ja auch nur aus bytes?!

Ich habs nich so mit net-programming....

Könntest du das was du gemeint hast näher erläutern?

mfg,
Filip
 
So!

Ich habe jetzt testweise folgende Klasse geschrieben:

Code:
package at.co.lipski.twcc.network;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class ProgressObjectOutputStream extends ObjectOutputStream {
	
	private int progress;
	private int length;
	
	public int getLength() {
		return length;
	}

	public void setLength(int length) {
		this.length = length;
	}

	public synchronized int getProgress() {
		int prog = progress/length*100;
		System.out.println(prog);
		return prog;
	}

	public ProgressObjectOutputStream(OutputStream o) throws IOException{
		super(o);
		progress = 0;
	}
	
	public void write(int b) throws IOException{
		super.write(b);
		progress++;
		System.out.print("Write (int b): ");
		getProgress();
	}
	
	public void writeByte(int b) throws IOException{
		super.writeByte(b);
		progress++;
		System.out.print("Write byte(int b): ");
		getProgress();
	}
}
Sobald die Methode write(int b) aufgerufen wird, sollte der Progress berechnet und probeweise in der Konsole ausgegeben werden.

wenn ich jetzt ein Objekt (ungefähr 700kb) mit writeObject(Object o) in den Stream schreibe, wird von writeObject(Object o) die Methode write(int b) anscheinend überhaupt nicht aufgerufen, writeByte(int b); ein paar mal,..

Der Output:

Code:
Write byte(int b): 0
Write byte(int b): 0
Write byte(int b): 0
Write byte(int b): 0

Die größe des Objekts habe ich erfahren durch die length von dem byte array welches ich hier bekommen habe:

Code:
	public static byte[] getBytes(Object obj) throws IOException{
	      ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
	      ObjectOutputStream oos = new ObjectOutputStream(bos); 
	      oos.writeObject(obj);
	      oos.flush(); 
	      oos.close(); 
	      bos.close();
	      byte [] data = bos.toByteArray();
	      return data;
	  }

writeObject benutzt also anscheinend write(byte[] b) und write(byte[] b, int off, int len).
Wenn ich die Methoden überschreibe kann ich wohl kaum die bytes zählen,...

Ich habe mir ja etwas anderes überlegt....
Ich schnappe mir das serialisierte Objekt mit Hilfe der Methode getBytes von oben, geh mit einer for-schleife durch das array und sende einzelne bytes....

Jedoch wirft die Maschine auf der anderen Seite eine exception bei der Methode readObject(). da primitives gesendet werden,....

Das muss doch irgendwie gehen -.-
 
Hallo,

schau mal hier:
Java:
package de.tutorials;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ObjectOutputStreamProgress {
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {

		Foo foo1 = new Foo(new byte[8 * 1024 * 1024]);

		System.out.println(foo1);

		final ProgressTrackingOutputStream ptos = new ProgressTrackingOutputStream(
				new BufferedOutputStream(new FileOutputStream("c:/temp/o.ser"),8192), new Progress(
						foo1.data.length + 8));
		
		ObjectOutputStream oos = new ObjectOutputStream(ptos);

		Executors.newSingleThreadExecutor().execute(new Runnable() {
			public void run() {
				while (ptos.getProgess().get() < 1.0) {
					System.out.println("Serialization: " + ptos.getProgess().get() * 100.f +"%");
					try {
						TimeUnit.MILLISECONDS.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println("Serialization completed");
			}
		});

		oos.writeObject(foo1);
		oos.close();

		final ProgressTackingInputStream ptis = new ProgressTackingInputStream(
				new FileInputStream("c:/temp/o.ser"), new Progress(
						foo1.data.length + 8));
		ObjectInputStream ois = new ObjectInputStream(ptis);

		Executors.newSingleThreadExecutor().execute(new Runnable() {
			public void run() {
				while (ptis.getProgess().get() < 1.0) {
					System.out.println("Deserialization: " + ptis.getProgess().get() * 100.f +"%");
					try {
						TimeUnit.MILLISECONDS.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println("DeSerialization completed");
			}
		});

		Foo foo2 = (Foo) ois.readObject();
		ois.close();

		System.out.println(foo2);

	}

	static class Foo implements Serializable {
		byte[] data;

		public Foo(byte[] data) {
			this.data = data;
		}

		public String toString() {
			return super.toString() + " " + data.length;
		}
	}

	static class ProgressTrackingOutputStream extends FilterOutputStream {
		private final Progress progess;

		public ProgressTrackingOutputStream(OutputStream out, Progress progess) {
			super(out);
			this.progess = progess;
		}

		public Progress getProgess() {
			return progess;
		}

		public void write(byte[] b, int off, int len) throws IOException {
			super.write(b, off, len);
			this.progess.update(len);
		}
	}

	static class ProgressTackingInputStream extends FilterInputStream {
		private final Progress progess;

		public ProgressTackingInputStream(InputStream in, Progress progess) {
			super(in);
			this.progess = progess;
		}

		public Progress getProgess() {
			return progess;
		}

		public int read(byte[] b, int off, int len) throws IOException {
			try {
				return super.read(b, off, len);
			} finally {
				this.progess.update(len);
			}
		}

	}

	static class Progress {
		private final long estimated;

		private volatile long actual;

		public Progress(long estimated) {
			this.estimated = estimated;
		}

		public long getEstimated() {
			return estimated;
		}

		public long getActual() {
			return actual;
		}

		public void update(long step) {
			this.actual += step;
		}

		public float get() {
			return actual * 1f / estimated;
		}
	}

}

Beispiel Ausgabe:
Code:
de.tutorials.ObjectOutputStreamProgress$Foo@a90653 8388608
Serialization: 4.7683672E-5%
Serialization: 71.25349%
Deserialization: 12.049366%
de.tutorials.ObjectOutputStreamProgress$Foo@e89b94 8388608
Serialization completed
DeSerialization completed

Eine Schätzung für Objekt-Größen in bytes bekommst entweder über:
http://www.tutorials.de/forum/java/...lung-platformspezifischer-objektgroessen.html

Oder:
http://www.javaspecialists.eu/archive/Issue142.html


Gruß Tom
 
Ganz kurz:

Funktioniert (fast: Denn wenn die laenge nicht stimmt bricht die schleife die den progress ausgibt ab. hab ich umgeschrieben :D)

Vielen Dank!
 

Neue Beiträge

Zurück