在Java中,是否有可能将包含BufferedImage作为其中一个对象的私有实例变量的对象ArrayList序列化?

4

我希望能够开发一款团队管理软件。我有一个Team对象:

public class Team implements Serializable{
    private String name;//
    private ArrayList<Player> teamMembers;//
    private String sport;//
    private ArrayList<Staff> staff;//Non-Player Members such as head coach, assisstant coach, physio, etc.
    private Object schedule;
    private String teamHometown;
    private String teamState;   

  // Getter and setter methods go here

    public Team(String name, String sport, ArrayList<Player> players, ArrayList<Staff> staff){
        teamMembers = players;
        this.staff = staff;
        this.sport =(sport);
        this.name = (name);

    }

}

团队对象包含一个Player对象的ArrayList。在每个Player对象中,球员有许多属性,例如姓名、统计信息和球员照片(一张缓冲图像):
public class Player implements Serializable{

    private BufferedImage playerPhoto;
    private String firstName;
    private String lastName;
    private int jerseyNumber;
    private String playerPosition;
    private String status;//Is the player Eligible to plays
    private int gameAbscenses;
    private int goals;
    private int appearances;
    private int yellowCards;
    private int redCards;
    private LocalDate birthday;
    private boolean starter;
    private int shots;
    private int shotsOnGoal;
    private int assists;

   //Getter and Setter Methods go here

    public Player(String firstName, String lastName, int jerseyNumber, String playerPosition,BufferedImage playerPhoto) {
        this.firstName = (firstName);
        this.lastName = (lastName);
        this.jerseyNumber = (jerseyNumber);
        this.playerPosition = (playerPosition);
        this.gameAbscenses = (0);
        this.status = ("Healthy");
        this.starter = false;

        //stats
        this.shots = (0);
        this.appearances = (0);
        this.shotsOnGoal = (0);
        this.redCards = (0);
        this.yellowCards = (0);
        this.assists =  (0);
        this.goals = (0);

        this.birthday = LocalDate.now();

    }

我的目标是将一个Team对象的ArrayList进行序列化,但Buffered Images不可被序列化。由于Player对象包含缓冲图像作为其私有实例变量之一,因此我无法对Team对象的ArrayList进行序列化。

我最初尝试了以下方法:

 ArrayList<Team> finalTeams = new ArrayList<>(SignInController.userTeams);//Converting the user teams Observable list to an Array List

            //Saving the user's Teams locally

            FileOutputStream fos = new FileOutputStream(SignInController.userfname+"'s Teams/"+SignInController.userfname+"_teams.xtm");
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(finalTeams);//serializing the ARRAYlist of teams
            oos.close();
            fos.close();

然而,它没有起作用。我还尝试查看其他与序列化缓冲图像相关的堆栈溢出问题,但没有什么能帮助我。

如果有人能解释一下我做错了什么,那就太棒了!谢谢!


如果缓冲图像是可序列化的,那么你不应该有任何问题。如果它不是可序列化的,这意味着只有在将此字段声明为“瞬态”时(即 - 它不会被序列化,这些信息不会通过网络传递),才能对对象进行序列化。 - Nir Alfasi
是的,我知道,但这正是我不想发生的事情。我想知道是否有办法对 BufferedImage 进行序列化。 - xkunle97
2个回答

2

可以的,为什么不呢?!但我们将采用非常规方法,并且这对我来说已经很好地起作用了。

  1. 众所周知,基本类型和基本类型数组都是可序列化的。
  2. 我们也知道,可以将缓冲图像实例转换为字节数组,反之亦然。
  3. 因此,我们将序列化表示此缓冲图像的字节数组,而不是序列化缓冲图像本身。

我创建了一个演示,模拟了您的问题。

import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
public class Member implements Serializable
{

    private String name;
    private byte[] imagebytes;

    public Member(String name, BufferedImage image) throws IOException
    {
        this.name = name;
        this.setImage(image);
    }

    public Member(String name, File imageFile) throws IOException
    {
        this.name = name;
        this.setImage(imageFile);
    }

    public final void setImage(BufferedImage image) throws IOException
    {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", outputStream);
        this.imagebytes = outputStream.toByteArray();
    }

    public final void setImage(File imageFile) throws IOException
    {
        BufferedImage bufferedImage = ImageIO.read(imageFile);
        this.setImage(bufferedImage);
    }


    public BufferedImage getImage()
    {

        try
        {
            return ImageIO.read(new ByteArrayInputStream(imagebytes));
        } catch (Exception io)
        {
            return null;
        }
    }

    public String getName()
    {
        return name;
    }

} 

您可以根据需要添加方法并自定义此类,希望这个答案对您有用。

成功了。谢谢! - xkunle97
1
好消息兄弟,这没什么,很高兴能帮忙。 - Anas

0

根据Javadocs

在序列化和反序列化过程中需要特殊处理的类必须实现具有以下精确签名的特殊方法:

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData()
     throws ObjectStreamException;

因此,您可以通过扩展BufferedImage并实现上述方法来创建自己的类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接