如何序列化ImageIcon对象?
How to Serialize ImageIcon Object?
我正在尝试构建一个客户端-服务器程序,其中服务器将图像发送到客户端,客户端在 JFrame 中显示接收到的图像。我正在将服务器端的图像转换为 ImageIcon 对象并通过 ObjecOutputStream 将其发送到客户端。但它失败了,并在服务器端给我 加载图像内容失败错误 ,它发生在调用 ObjectOutputStream.writeObject() 方法时。
服务器端代码
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ImageServer{
private static ServerSocket serverSocket;
private static final int PORT = 1234;
public static void main(String[] args){
System.out.println("Opening port…\n");
try{
serverSocket = new ServerSocket(PORT);
}
catch(IOException ioEx){
System.out.println("Unable to attach to port!");
System.exit(1);
}
while(true){
try{
Socket connection = serverSocket.accept();
ObjectOutputStream outStream =new ObjectOutputStream(
connection.getOutputStream());
ImageIcon icon=new ImageIcon("//Give image path//");
System.out.println(icon.getImageLoadStatus());// To check if image is loded correctly or not.
outStream.writeObject(icon);
outStream.flush();
}
catch(IOException ioEx){
ioEx.printStackTrace();
}
}
}
}
只给出图片文件的路径,以供测试。
客户端代码
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ImageClient extends JFrame{
private InetAddress host;
private final int PORT = 1234;
private ImageIcon image;
public static void main(String[] args){
ImageClient pictureFrame = new ImageClient();
pictureFrame.setSize(340,315);
pictureFrame.setVisible(true);
pictureFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public ImageClient(){
try{
host = InetAddress.getLocalHost();
}
catch(UnknownHostException uhEx){
System.out.println("Host ID not found!");
System.exit(1);
}
try{
Socket connection = new Socket(host,PORT);
ObjectInputStream inStream =new ObjectInputStream(
connection.getInputStream());
image = (ImageIcon)inStream.readObject();
connection.close();
}
catch(IOException ioEx){
ioEx.printStackTrace();
}
catch(ClassNotFoundException cnfEx){
cnfEx.printStackTrace();
}
repaint();
}
public void paint(Graphics g){
image.paintIcon(this,g,0,0);
}
}
服务器端产生错误
java.io.IOException: failed to load image contents
at javax.swing.ImageIcon.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at ImageServer.main(ImageServer.java:27)
这是以下书中的代码摘录:
http://www.springer.com/us/book/9781447152538
好的,所以我使用 Netbeans 创建了一个项目。我在名为 images
.
的包中放置了一张图片(名为 29bd6417998561.5635a605ad357.png
我创建了 Server
class...
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class Server {
private static final int PORT = 9999;
public static void main(String[] args) {
System.out.println("Opening port…\n");
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
while (true) {
;
try {
System.out.println("Waiting for connection");
Socket connection = serverSocket.accept();
System.out.println("Read image...");
ImageIcon icon = new ImageIcon(ImageIO.read(Server.class.getResource("/images/29bd6417998561.5635a605ad357.png")));
System.out.println("Read image...");
try (ObjectOutputStream outStream = new ObjectOutputStream(connection.getOutputStream())) {
System.out.println("Write image");
outStream.writeObject(icon);
}
} catch (IOException ioEx) {
ioEx.printStackTrace();
}
}
} catch (IOException ioEx) {
System.out.println("Unable to attach to port!");
System.exit(1);
}
}
}
并创建了 Client
class...
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Client {
private InetAddress host;
private final int PORT = 9999;
private ImageIcon image;
private JLabel label;
public static void main(String[] args) {
Client pictureFrame = new Client();
}
public Client() {
try {
host = InetAddress.getLocalHost();
} catch (UnknownHostException uhEx) {
System.out.println("Host ID not found!");
System.exit(1);
}
JFrame frame = new JFrame();
label = new JLabel();
frame.add(label);
System.out.println("Connect to server");
try (Socket connection = new Socket(host, PORT)) {
try (ObjectInputStream inStream = new ObjectInputStream(connection.getInputStream())) {
System.out.println("Read image");
image = (ImageIcon) inStream.readObject();
label.setIcon(image);
System.out.println("All done");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
} catch (IOException ex) {
ex.printStackTrace();
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
我启动了 Server
和 运行 以及 Client
并且运行良好...
免责声明...
毫无疑问,其他人会指出此代码的固有问题,但这不是示例的重点。
首先,您永远不应该在事件调度线程中执行阻塞或长 运行 操作(例如连接到服务器 and/or 从中读取图像)。你也不应该从事件调度线程的上下文之外修改 UI(这里有点安全,因为框架没有在屏幕上实现,但仍然不是一个很好的例子)。
在这两种情况下,SwingWorker
之类的东西将有助于解决这些问题。
查看 Work Threads and SwingWorker 了解更多详情
我正在尝试构建一个客户端-服务器程序,其中服务器将图像发送到客户端,客户端在 JFrame 中显示接收到的图像。我正在将服务器端的图像转换为 ImageIcon 对象并通过 ObjecOutputStream 将其发送到客户端。但它失败了,并在服务器端给我 加载图像内容失败错误 ,它发生在调用 ObjectOutputStream.writeObject() 方法时。
服务器端代码
import java.io.*;
import java.net.*;
import javax.swing.*;
public class ImageServer{
private static ServerSocket serverSocket;
private static final int PORT = 1234;
public static void main(String[] args){
System.out.println("Opening port…\n");
try{
serverSocket = new ServerSocket(PORT);
}
catch(IOException ioEx){
System.out.println("Unable to attach to port!");
System.exit(1);
}
while(true){
try{
Socket connection = serverSocket.accept();
ObjectOutputStream outStream =new ObjectOutputStream(
connection.getOutputStream());
ImageIcon icon=new ImageIcon("//Give image path//");
System.out.println(icon.getImageLoadStatus());// To check if image is loded correctly or not.
outStream.writeObject(icon);
outStream.flush();
}
catch(IOException ioEx){
ioEx.printStackTrace();
}
}
}
}
只给出图片文件的路径,以供测试。
客户端代码
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ImageClient extends JFrame{
private InetAddress host;
private final int PORT = 1234;
private ImageIcon image;
public static void main(String[] args){
ImageClient pictureFrame = new ImageClient();
pictureFrame.setSize(340,315);
pictureFrame.setVisible(true);
pictureFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public ImageClient(){
try{
host = InetAddress.getLocalHost();
}
catch(UnknownHostException uhEx){
System.out.println("Host ID not found!");
System.exit(1);
}
try{
Socket connection = new Socket(host,PORT);
ObjectInputStream inStream =new ObjectInputStream(
connection.getInputStream());
image = (ImageIcon)inStream.readObject();
connection.close();
}
catch(IOException ioEx){
ioEx.printStackTrace();
}
catch(ClassNotFoundException cnfEx){
cnfEx.printStackTrace();
}
repaint();
}
public void paint(Graphics g){
image.paintIcon(this,g,0,0);
}
}
服务器端产生错误
java.io.IOException: failed to load image contents
at javax.swing.ImageIcon.writeObject(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at ImageServer.main(ImageServer.java:27)
这是以下书中的代码摘录: http://www.springer.com/us/book/9781447152538
好的,所以我使用 Netbeans 创建了一个项目。我在名为 images
.
29bd6417998561.5635a605ad357.png
我创建了 Server
class...
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class Server {
private static final int PORT = 9999;
public static void main(String[] args) {
System.out.println("Opening port…\n");
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
while (true) {
;
try {
System.out.println("Waiting for connection");
Socket connection = serverSocket.accept();
System.out.println("Read image...");
ImageIcon icon = new ImageIcon(ImageIO.read(Server.class.getResource("/images/29bd6417998561.5635a605ad357.png")));
System.out.println("Read image...");
try (ObjectOutputStream outStream = new ObjectOutputStream(connection.getOutputStream())) {
System.out.println("Write image");
outStream.writeObject(icon);
}
} catch (IOException ioEx) {
ioEx.printStackTrace();
}
}
} catch (IOException ioEx) {
System.out.println("Unable to attach to port!");
System.exit(1);
}
}
}
并创建了 Client
class...
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Client {
private InetAddress host;
private final int PORT = 9999;
private ImageIcon image;
private JLabel label;
public static void main(String[] args) {
Client pictureFrame = new Client();
}
public Client() {
try {
host = InetAddress.getLocalHost();
} catch (UnknownHostException uhEx) {
System.out.println("Host ID not found!");
System.exit(1);
}
JFrame frame = new JFrame();
label = new JLabel();
frame.add(label);
System.out.println("Connect to server");
try (Socket connection = new Socket(host, PORT)) {
try (ObjectInputStream inStream = new ObjectInputStream(connection.getInputStream())) {
System.out.println("Read image");
image = (ImageIcon) inStream.readObject();
label.setIcon(image);
System.out.println("All done");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
} catch (IOException ex) {
ex.printStackTrace();
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
我启动了 Server
和 运行 以及 Client
并且运行良好...
免责声明...
毫无疑问,其他人会指出此代码的固有问题,但这不是示例的重点。
首先,您永远不应该在事件调度线程中执行阻塞或长 运行 操作(例如连接到服务器 and/or 从中读取图像)。你也不应该从事件调度线程的上下文之外修改 UI(这里有点安全,因为框架没有在屏幕上实现,但仍然不是一个很好的例子)。
在这两种情况下,SwingWorker
之类的东西将有助于解决这些问题。
查看 Work Threads and SwingWorker 了解更多详情