2014-10-13 7 views
1

클라이언트에서 Java 서버의 소켓을 통해 JPEG 이미지를 보내려고합니다. 이미지를 File 객체에 쓴 다음 FileInputStream을 사용하여 소켓을 통해 배열을 보내기 전에 Byte [] 배열로 읽습니다. 아래는 클라이언트 용 코드입니다.Java에서 소켓을 통해 JPG 이미지를 보내면 JPG 이미지가 손상되거나 손상됩니다.

class TestingClient { 
    Socket s; 
    public TestingClient() { 
     try { 
      s = new Socket("localhost", 666); 
     }catch (UnknownHostException e){ 
      e.printStackTrace(); 
     }catch (IOException e){ 
      e.printStackTrace(); 
     } 
     String imgPath = "C:/Users/huehuehue/Documents/Uni/D0036D/prick1.JPG"; 
     File file = new File(imgPath); 
     byte[] bFile = new byte[(int) file.length()]; 
     try { 
      FileInputStream fin = new FileInputStream(file); 
      fin.read(bFile); 
      fin.close(); 
      OutputStream os = s.getOutputStream(); 
      os.write(bFile, 0, bFile.length); 
      os.close(); 
      System.out.println(); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

서버는 두 개의 ".JPG"-files로 받았다 바이트에서 기록하고 간단한 JFrame의에 추가 할 때 JLabel의 인스턴스화시에 호출되는 버퍼링 된 이미지로 받았다 바이트를 판독한다. 파일 자체는 "파일이 손상되었거나 손상되었거나 너무 큽니다"라는 이유로이 사진을 열 수 없다는 Windows 사진 뷰어를 통해 볼 수 없습니다. 프로그램이 버퍼링 된 이미지로 JLabel을 인스턴스화하려고하면 처리되지 않은 예외 "java.lang.NullPointerException"이 발생합니다. 모든 콘솔 메시지는 코드대로 출력됩니다. 아래는 서버 코드입니다.

public class TestingServer { 

    InetAddress serverAddr; 
    BufferedImage img; 

    private class frame extends JFrame { 

     JLabel test; 

     private class aspectRatio { 
      int w = 16, h = 9; 
     } 

     public frame (BufferedImage y) { 
      aspectRatio aR = new aspectRatio(); 
      this.setVisible(true); 
      this.setSize(50*aR.w, 50*aR.h); 
      this.setTitle("TESTING"); 
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      this.setLayout(null); 
      this.getContentPane().setBackground(Color.DARK_GRAY); 

      this.add(test = new JLabel(new ImageIcon(y))); 
      test.setBounds(25*aR.w, 13*aR.h, 15*aR.w, 10*aR.h); 
     } 

    } 

    public TestingServer() { 
     ServerSocket serverSocket; 
     try { 
      serverSocket = new ServerSocket(666); 
      Socket connect = serverSocket.accept(); 

     System.out.println("So we read"); 
     InputStreamReader ir = new InputStreamReader(connect.getInputStream()); 
     FileOutputStream fos1 = new FileOutputStream(new File("C:/Users/huehuehue/Documents/Uni/D0036D/test1.JPG")); 
     int c=0; 
     while ((c = ir.read()) != -1) { 
      fos1.write(ir.read()); 
     } 
     fos1.close(); 
     System.out.println("finito1"); 

     FileOutputStream fos2 = new FileOutputStream(new File("C:/Users/huehuehue/Documents/Uni/D0036D/test2.JPG")); 
     byte[] barr = new byte[34534]; 
     int i = 0; 
     c = 0; 
     while ((c = ir.read()) != -1) { 
      barr[i] = (byte) c; 
      i++; 
     } 
     fos2.write(barr,0,i+1); 
     fos2.close(); 
     System.out.println("finito2"); 

     img = ImageIO.read(ImageIO.createImageInputStream(new ByteArrayInputStream(barr, 0, i))); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("image buffered"); 

     frame f = new frame(img); 

    } 

} 

나는 갇혀 있고 어떤 도움이나지도가 고맙게 여기고 있습니다. :) 미리 감사드립니다!

답변

2

이미지의 바이트를 문자로 변환하려고하는 InputStreamReader를 사용하고 있습니다. 독자가 없으면 InputStream을 직접 사용해야합니다. 또는 바람직하게는 다음을 사용하십시오. BufferedInputStream

또한 두 번째 파일을 채우는 동안 이미 입력 스트림에서 스트림의 끝을 나타내는 -1이 표시 되어도 계속 읽습니다. 대신 루프 앞에서 두 파일을 열고 입력 스트림에서 읽은 바이트를 첫 번째 파일에 한 번, 두 번째 파일에 두 번 작성해야합니다.

또 다른 문제는 ir.read()을 루프 (첫 번째 파일 채우기)에서 다시 호출하는 것입니다. 이것은 이미 읽은 바이트를 버리고 다음 바이트를 읽습니다. 따라서 본질적으로 두 번째 바이트를 모두 읽습니다. 내가 대신 파일을 .txt로 그들을를 작성하려고 할 때 2 파일이 비어 밝혀졌다 특히 왜 많은 정리 응답을

iStream = new BufferedInputStream(connect.getInputStream()); 

FileOutputStream fos1 = new FileOutputStream(new File("C:/Users/huehuehue/Documents/Uni/D0036D/test1.JPG")); 
FileOutputStream fos2 = new FileOutputStream(new File("C:/Users/huehuehue/Documents/Uni/D0036D/test2.JPG")); 
int c=0; 
while ((c = iStream.read()) != -1) { 
    fos1.write(c); 
    fos2.write(c); 
} 
fos1.close(); 
fos2.close(); 
iStream.close(); 
+0

감사 :

그래서 당신의 라인을 따라 뭔가를 할 필요가있다. 왜 데이터가 바로 그것을 읽는 즉시 손실되지 않습니다 (오른쪽?) BufferedInputStream 더 좋을 것이라고 볼 수있을 것 같아요,하지만 여기에 필요 한가? – crimsoncheesecake

+0

아니요. 실제로, 한 번에 한 바이트 씩 읽는 것이 시스템 호출에 많은 오버 헤드를 유발하기 때문입니다. BufferedInputStream는 여러 바이트를 함께 읽으며 모든 시스템에 대해 단일 시스템 호출 만 수행하고이를 버퍼에 보관합니다. 다음 바이트를 요청하면 버퍼에서 버퍼를 가져 와서 많은 시스템 자원을 저장합니다. – RealSkeptic