# Einfacher Filedownload mit Sockets geht nicht für pdffiles



## coolex (31. Mai 2007)

Hallo!

Ich möchte einen Fileserver programmieren. 
Es handelt sich dabei um eine Socket Lösung und die Dateien sollen dann über Streams runtergeladen werden.
Auf Anfrage des Clients liest der Server die Dateien zeilenweise ein und verschickt sie dann gleich wieder an den Client. 
Auf der Clientseite "sammle" ich die ankommenden Zeilen wieder ein und bastle mit denen dann eine Datei zusammen. 
Leider funktioniert diese Methode nicht für z.B. Pdf dateien. Die Pdf datei wird zwar erstellt (mit falscher Dateigröße), aber ich kannn sie nicht öffnen. :-(
Für Textdateien geht das wunderbar.

Welche Streams sollte man dafür grundsätzlich nutzen?

Ich hoffe, ihr könnt mir helfen.

Danke.
 Alex


----------



## kleiner_held (31. Mai 2007)

Du liest die PDF Datei *zeilenweise* ein?
Klingt fuer mich so, also wuerdest du deine Binaerdaten in Strings konvertieren.

Dein Sender sollte ungefaehr so arbeiten:
 Die Daten aus einem FileInputStream unter Mithilfe eines byte[] Arrays gleich in den Socket-OutputStream kopieren.
Beim Empfaenger dann genau umgedreht:
 Vom Socket-InputStream in den FileOutputStream kopieren.


----------



## coolex (1. Jun 2007)

Danke für die schnelle Antwort.

Ich nun auf der Serverseite es geschafft, dass er nun mit den "normalen" Sttreams arbeitet. Er schreibt also zunächst die Datei in ein bytearray (byte[]) und verschickt diesen sofort in den outputstream des sockets.

Allerdings kämpfe ich schon die ganze Zeit auf der Clientseite und komme nicht weiter, wie ich nun die ankommenden Daten in eine Datei schreiben soll. Ich habe mir auch überlegt den BufferedInputStream zur Hilfe zu nehmen, was bei mir auch nicht funktioniert hat. 
Eines meiner größten Probleme ist die Größe des byte arrays. Ich habe es bisher nicht geschafft, dass die Größe während der Laufzeit, je nach dem wie größ die Datei werden soll, festgelegt wird. 

Ich habe da Dinge stehen, wie z.B.

```
inStream = socket.getInputStream();
fileArray = new byte[1000000]; // hier weiß ich nicht, wie ich es dynamischer machen soll
inStream.read(fileArray);
fileOutStream.write(fileArray);
fileOutStream.flush();
```

Ich bin langsam am verzweifeln. Ich hoffe, ihr könnt mir weiterhelfen.
Danke.

Alex


----------



## HoaX (1. Jun 2007)

braucht du nicht, du kannst so oft kleine blöcke an daten lesen/schreiben bis das ende erreicht ist.


----------



## coolex (1. Jun 2007)

Meinst du, dass ich keinen BufferedInputStream brauche? 
Kannst du eventuell ein Beispiel angeben, was du meinst?

danke


----------



## HoaX (1. Jun 2007)

du baust die eine schleife die solange läuft bis nichtsmehr im inputstream is. in der schleife liest du den stream häppchenweise ein und schreibst ihn ebenso in die datei.


----------



## coolex (1. Jun 2007)

Also sowas wie das vielleicht:


```
inStream = socket.getInputStream();

byte b;
while((b = (byte)inStream.read()) >= 0 && (b = (byte)inStream.read()) <= 256){
    fileOutStream.write(b);
}

fileOutStream.flush();
```

Oder fehlt noch was?


----------



## kleiner_held (1. Jun 2007)

Normalerweise macht man es so:


```
private void copy(InputStream in, OutputStream out) throws IOException
{
	// buffer fuer die daten anlegen
	byte[] buffer = new byte[102400]; // 100 kByte
	int cnt; 
	// return von read ist die anzahl der gelesenen bytes, wenn -1 dann
	// ist der Stream zuende
	while ((cnt = in.read(buffer)) > -1) 
	{
		// alles was gelesen wurde auch wieder rausschreiben
		out.write(buffer, 0, cnt);
	}
	out.flush();
}

// server
InputStream in = new FileInputStream("C:\\in.pdf");
OutputStream out = socket.getOutputStream();
copy(in, out);
in.close();

// client
InputStream in = socket.getInputStream();
OutputStream out = new FileOutputStream("C:\\out.pdf");
copy(in, out);
out.close();
```


----------



## HoaX (1. Jun 2007)

coolex hat gesagt.:
			
		

> Also sowas wie das vielleicht:
> 
> 
> ```
> ...



so auf jedenfall nicht!

a) bytes einzeln zu lesen ist seeeeehr inperformant

b) was da gelesen wird ist ein int, kein byte, lass es einfach so

c) ein byte ist immer <=128 in java

d) du rufst 2 mal read auf, aber nur einmal write ... du speicherst nur jedes zweite zeichen


----------



## coolex (1. Jun 2007)

Vielen Dank!
Die Lösung von dem "kleinen Held" hat mir am besten geholfen.

Also nochmals vielen dank.


----------



## coolex (3. Jun 2007)

Hallo!

Mir ist aufgefallen, dass dies für pdf dateien nicht funktioniert. :-(
Woran kann es denn liegen?

Alex


----------



## kleiner_held (3. Jun 2007)

Da musst du schon ein paar Details mehr geben, wenn du willst, dass dir geholfen wird.
Das byteweise Kopieren mit Hilfe von Input- / Outputstreams funktioniert für alle Dateien unabhängig vom Inhalt. Wenn bei dir etwas nicht klappt, dann nicht weil es eine PDF-Datei ist, sondern weil ein Programmierfehler vorliegt.


----------



## coolex (3. Jun 2007)

Nun gut. 
Ich habe deine copy methode benutzt. 
Das downloaden funktioniert. Die Dateigröße stimmt auch. Alles wunderbar, ABER wenn ich die PDF datei öffnen will, bekomme ich eine Fehlermeldung :-(
MP3 werden problemlos runtergeladen. Ich kann sie auch öffnen und abspielen.

alex


----------



## kleiner_held (3. Jun 2007)

Aber die originale PDF Datei lässt sich problemlos öffnen?
Hast du schon mal die originale Datei und die durch dein Programm downgeloadete Datei inhaltlich (binär) miteinander verglichen?


----------



## coolex (3. Jun 2007)

Die originale PDF datei lässt sich problemlos öffnen. 
Einen Binärvergleich habe ich nicht gemacht. Was genau meinst du damit? Wie soll das gemacht werden?


----------



## coolex (3. Jun 2007)

Moment, ich habe den Fehler nun selbst gefunden. Der Fehler lag darin, dass mein Programm die PDF datei noch benutzt hat und deshalb der Acrobat Reader sie nicht öffnen wollte. 
Nun geht es.

Trotzdem vielen Dank für die Hilfe.

Alex


----------



## kleiner_held (3. Jun 2007)

Man kann z.B.: mit Diff (der Artikel enthält auch Links zu freien Windowsimplementierungen) zwei Dateien binär vergleichen. Damit kann man rausfinden, ob sie sich überhaupt unterscheiden und falls ja, worin sie sich unterscheiden.

Edit: Ok, hat sich also erledigt. Na dann viel Erfolg noch


----------

