2016-04-11 5 views
0

Dieses Programm sollte das angegebene Bild von Flicker herunterladen. Es ist eine Hausaufgabenfrage, ich muss Socket verwenden. Mein Programm führt die HTTP-Anfrage erfolgreich durch und empfängt die Antwort. Ich eliminiere Header und schreibe Bytes in eine JPG-Datei. Aber wenn ich es mit einem Bildbetrachtungsprogramm geöffnet werden soll, heißt es:Kodierung Spezifikation wird benötigt, wenn Sie ein Bild über Java-Socket herunterladen?

Fehler zu interpretieren JPEG-Bilddatei (Falschen Aufruf JPEG-Bibliothek in Zustand 200

So heruntergeladen ich das Bild separetly und in einem Texteditor geöffnet, so scheint es, wie einige Teile davon nicht umgewandelt wird

Originaldatei.

\ FF \ D8 \ FF \ E0 \ 00JFIF \ 00 \ 00 \ 00 \ 00 \ 0 0 \ 00 \ FF \ E2 \ A0ICC_PROFILE

heruntergeladene Datei:

ᅵᅵᅵᅵ \ 00JFIF \ 00 \ 00 \ 00 \ 00 \ 00 \ 00ï¿œï¿ -

Ist das Zeichencodierung? Wenn ja, wie sollte ich die Codierung angeben? Oder was soll ich tun, um JPEG-Datei wirklich zu bekommen?

public class ImageReceiver { 
public static void main(String[] args) { 
    String imglink = "https://farm2.staticflickr.com/1495/26290635781_138da3fed8_m.jpg"; 
    String flicker = "farm2.staticflickr.com"; 

    Socket socket = null; 
    DataOutputStream out; 

    try { 
     socket = new Socket(flicker, 80); 
     out = new DataOutputStream(socket.getOutputStream()); 

     out.writeBytes("GET "+ imglink +" HTTP/1.1\r\n"); 
     out.writeBytes("Host: "+ flicker +":80\r\n\r\n"); 
     out.flush(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    DataInputStream in = null; 
    OutputStream output = null; 

    try { 
     in = new DataInputStream(socket.getInputStream()); 
     output = new FileOutputStream("chair.txt"); 

     System.out.println("input connection is established"); 

     byte[] bytes = new byte[2048]; 
     int length;  
     boolean eohFound = false; 

     while ((length = in.read(bytes)) != -1) { 
      if(!eohFound){ 
       String string = new String(bytes, 0, length); 
       int indexOfEOH = string.indexOf("\r\n\r\n"); 
       if(indexOfEOH != -1) { 
        System.out.println("index: " + indexOfEOH); 
        length = length - indexOfEOH - 4; 
        System.out.println(length); 
        bytes = string.substring(indexOfEOH + 4).getBytes(); 
        eohFound = true; 
       } else { 
        length = 0; 
       } 
      } 
      output.write(bytes, 0, length); 
      output.flush(); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 


    try { 
     in.close(); 
     output.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    System.out.println("Image is downloaded"); 

} 

}

+2

Sie können nicht davon ausgehen, die gesamte '\ r \ n \ r \ n 'Sequenz in einer einzigen Lese ankommt , und Sie können 'String' sicherlich nicht als Container für Binärdaten verwenden. Ich würde zuerst alle Kopfzeilen lesen und dann die Kopierschleife starten. – EJP

+0

Wenn ich indexOfEOH und Länge drucken (wenn Sie den Code ausführen, druckt es sie), scheint es mir in Ordnung. Ich meine, es ist der Index. Sonst sollte es nie ins Innere kommen, wenn, oder? Wie sollte ich Kopfzeilen lesen, um sicherzustellen, dass ich in \ r \ n \ r \ n ankomme? – user3717434

+1

Mit 'DataInputStream.readLine()', und ja, ich weiß, dass es veraltet ist. – EJP

Antwort

1

Mit Hilfe von EJP, schrieb ich meinen Code. Hier nur modifizierter Teil. Ich Readline-(), bis ich die neue Linie zu bekommen, dann habe ich als Bytes lesen und schreiben in Datei:

try { 
     in = new DataInputStream(socket.getInputStream()); 
     output = new FileOutputStream("chair.jpg"); 

     byte[] bytes = new byte[2048]; 
     int length; 

     String inputLine; 

     //Get rid of headers... 
     while ((inputLine = in.readLine()) != null){ 
      if(inputLine.equals("")) 
       break; 
     } 


     while ((length = in.read(bytes)) != -1) { 
      output.write(bytes, 0, length); 
      output.flush(); 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    }