int序列化java的数组

时间:2011-10-22 02:49:25

标签: java sockets

我有一个int数组,我希望使用套接字编程将其发送到其他服务器,但它无法正常工作我想知道我应该加强我的数组吗?

 public Integer[] array=new Integer[5]; 
 //I give some dummy value to array then I send. I have no error and the other side
 // receive it but with wrong value      
 in=new ObjectInputStream(client.getInputStream());
 out=new ObjectOutputStream(client.getOutputStream());
 out.writeObject(new packet(array));  

  import java.io.Serializable;
  public class packet implements Serializable
   {
     public Integer[] vec=null;
     public packet(Integer[] vector){
     vec=vector;}
   }
  //On the other side I have in=new ObjectInputStream(client.getInputStream());
    private packet getPacket() throws IOException
    {
        packet p;
    try {
            p=(packet) in.readObject();
            if (p != null)              
                return p;
        } 
    }

   `

4 个答案:

答案 0 :(得分:2)

这里的一切都还可以。然而,魔鬼在细节中。很明显,这不是真正的代码,而是你对代码的总结,所以你在总结它时偶然修复了一些东西。您遇到的最可能的问题是,Java序列化默认情况下只会将给定对象写入流一次;因此,如果您编写一个数组,更改内容,然后再次写入,第二个实例将作为第一个参考,只有第一个值的参考。像其他人提到的那样,在“数据包”构造函数中克隆数组肯定会有所帮助!

答案 1 :(得分:1)

我认为这不是一个好主意:

public class packet implements Serializable {

    public Integer[] vec=null;

    public packet(Integer[] vector) {
       vec=vector;
    }
}

一个公共的,可变的成员变量?并且以这种方式分配使得任何人都可以改变分组的状态。

以下是我如何重写您发布的位:

public class Packet implements Serializable {

    private Integer [] vector;

    public Packet(Integer [] vector) {
       this.vector = new Integer[vector.length];
       System.arraycopy(0, vector, 0, this.vector, vector.length);
    }
}

答案 2 :(得分:1)

如果您创建数组int[]而不是Integer[],则可以节省大约90%的序列化空间要求。除此之外,如果您了解ObjectOutputStream.reset()/writeUnshared()的用途,则没有理由说明您的代码无法正常运行。

此外,除非您计划发送空值,否则测试readObject() null的结果毫无意义。它在EOS中不会返回null,因为很多人似乎首先得出结论:它会抛出一个EOFException。

答案 3 :(得分:1)

我非常喜欢这个问题,它对我非常有帮助。我只想添加一些我刚学到的东西来完整。

  • EJP的回答没那么有用。他想考虑使用writeUnshared。鉴于packet问题的实施,他的方法无法帮助您解决问题,因为

      

    上述规则仅适用于使用writeUnshared编写的基础级对象,而不适用于要序列化的对象图中的任何可传递引用的子对象

    来源:ObjectOutputStream.writeUnshared
    换句话说,int数组的“子对象”不会受writeUnshared的影响。

  • 我在StackOverflow上看到了多个多维数组请求。我认为值得一提的是,第一维上对arraycopy的简单调用无法完成这项工作。您必须手动复制每个不包含数组的数组。给定上面的数据包带有二维整数数组,它看起来像这样(必须添加int[][]参数的构造函数):

    public packet copy() {
        // lets assume it's a square matrix
        int[][] temp = new BoardItem[vec.length][vec.length];
        for(int i = 0; i < vec.length; i++) {
            System.arraycopy(vec[i], 0, temp[i], 0, vec.length);
        }
        return new packet(temp);
    }
    

    在此修改之后,基本程序将是

    1. 创建packet
    2. 发送对象
    3. 改变vec
    4. 通过调用最近添加的copy方法
    5. 发送新的数据包对象
    6. 如果没有完成则从3开始重复

我个人使用这些步骤反复更改网络游戏的主板并向客户发送正确的数据。

相关问题