我正在尝试通过套接字将JPEG图像从客户端发送到java中的服务器。我将图像写入File-object然后使用FileInputStream我将它读入Byte []数组,然后通过套接字发送数组。以下是客户的代码。
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”文件,然后将收到的字节读入缓冲图像,在将JLabel添加到简单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);
}
}
我有点卡住了,感谢任何帮助或指导:)提前致谢!
答案 0 :(得分:2)
您正在使用InputStreamReader,它尝试将图像的字节转换为字符。您应该直接使用InputStream,而无需使用Reader。或者最好使用BufferedInputStream
此外,在填充第二个文件时,您继续从输入流中读取,尽管它已经给出-1表示流的结束。相反,您应该在循环之前打开这两个文件,并将您从输入流中读取的字节写入两次 - 一次进入第一个文件,一次进入第二个文件。
另一个问题是你在循环内再次调用ir.read()
(填充第一个文件)。这会丢弃您已读取的字节,并读取下一个字节。所以从本质上讲,你正在阅读每一个字节。
所以你需要做一些事情:
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();