# Problem beim Senden von Dateien



## VdA (17. Okt 2007)

Hi leute!

Ich bin grade auf ein Problem gestoßen.
Ich habe zwei Klassen geschrieben um eine Datei über das Netzwerk zu versenden
Eine für den Client und eine Für den Server
Nun soll eine Datei vom Client zum Server gesendet werden.

Client:

```
try{		
//hier wartet er bis der Stream schon verfügbar ist					while((filetransferstreams=com.streams.get(AbstractCommunication.FILETRANSFER_KOMMUNIKATION)) == null)Thread.sleep(1000);
	System.out.println("Starting uploading "+file+" to server.");
	ObjectOutputStream fileout = filetransferstreams.getOut();
	FileInputStream filein=new FileInputStream(file);
	
        //Und hier fängt er an die Datei einzulesen und zu senden
        //ist zwar nicht sehr perfomant aber mir ist keine andere Möglichkeit eingefallen 
       //den Fortschritt des Downloads zu berechnen
        int filesize=(int) file.length();
	for(int i=0;i<filesize;i++)
	{
		byte[] buffer=new byte[1];
		filein.read(buffer);
		fileout.write(buffer);
	}
}catch(Exception e){e.printStackTrace();}
```

Server:

```
//Hier die methode zum einlesen der versendeten Daten:
for(int i=0; i<downloaded.getMaximum(); i++)   //downloaded.getMaximum() entspricht filesize
//Solange ausführen bis das ende der Datei erreicht ist
{
	byte[] buffer=new byte[1];
	streams.getIn().read(buffer);
	streams.getOut().write(buffer);
		
        //Hier wird der Fortschritt berechnet		
	EventQueue.invokeLater(new Runnable(){
		public void run() {
			downloaded.setValue(downloaded.getValue()+1);
			downloads.repaint();
			timeElapsed=(int) (new Date().getTime()-startingtime.getTime());
			if(timeElapsed==0)timeElapsed=1;
			timeRemaining=(
				new BigDecimal(downloaded.getMaximum())
				.divide((new BigDecimal(downloaded.getValue())
					.divide(new BigDecimal(timeElapsed), 10, BigDecimal.ROUND_DOWN)
				), 10, BigDecimal.ROUND_DOWN)
				.subtract(new BigDecimal(timeElapsed))).intValue();
					}
				});
      //Das ist nur als Kontrolle wenn er "1" printet ist erfertig
     //leider kommt er nie Soweit *schnüff*
      System.out.println(downloaded.getMaximum()-i);
			}
```


Mein Problem ist jetzt das er immer so ungefähr 1000 bytes vorm ende Aufhört und in der for schleife steckenbleibt beim lesen aus dem InputStream

Ich habe leider keine Ahnung woran das liegt :autsch: 
Kann mir jemand helfen?


----------



## Murray (17. Okt 2007)

Mach mal beim Schreiben am Ende

```
fileout.flush();
```
ObjectInputStream fasst primitive Daten (hier: bytes) immer zu Blöcken von 1024 Bytes zusammen.

Eigentlich sind ObjectOutputStream und ObjectInputStream auch nicht dafür gedacht, einfach nur primitive Bytes durch die Gegend zu schicken; vielmehr können hier komplexe Objekte serialisiert, übertragen und auf der anderen Seite wieder deserialisiert werden - zum Übertragen von Dateien wäre die KOmbination (Buffered)OutputStream und (Buffered)InputStream besser geeignet.


----------



## VdA (17. Okt 2007)

Hm ja ich benutze Object(Input/Output)Streams weil ich mehrere Streams hab, die ich mit selbstprogrammierten Stream Objecten logisch geordnet hab.
Da ich die Streams Klasse so Programmiert hab, dass sie nur Object(Input/Output)Streams annimt bzw. Streams dazu hochwertet hatte sich das so ergeben.
Naja kann man ja noch ändern.
Bin auf jedenfall richtig froh, dass es jetzt geht.
thx

Edit:
Wenn ich jetzt aber Bilder damit versende, sieht es so aus aus als wären sie durch den Reiswolf gegangen.
Irgendwas macht er falsch bei schreiben der bytes ???:L


----------



## Murray (18. Okt 2007)

Was du mit einem ObjectOutputStream schreibt, musst du auch mit einem ObjectInputStream lesen, denn da werden neben den reinen Nutzdaten (also den hier den Bytes) noch irgendwelche Verwaltungsinformationen geschrieben (quasi "jetzt kommen 768 bytes",[768 bytes], "jetzt kommen 5 ints",[ 5 ints] usw). Wenn du diesen Datenstrom jetzt einfach byte-weise interpretierst, muss das schiefgehen.
Wenn du schon mit ObjectIn/OutputStream arbeiten musst, kannst du die Dateien vielleicht in serialisierbare Objekte verpacken. Alternativ kannst du wohl mit ObjectOutputStream#writeByte( int val) und ObjectInputStream#readByte() arbeiten.


----------



## VdA (18. Okt 2007)

nagut ich baus um auf den Kram hab ich keinen Bock dann doch lieber BufferedOutPutstream

EDIT: So jetzt benutz ich BufferedOut(/In)putStreams und das ganze funzt perfekt
War zwar ne riesen Arbeit das umzubauen aber es hat sich gelohnt


----------

