Массив int сериализации Java - PullRequest
       1

Массив int сериализации Java

1 голос
/ 22 октября 2011

У меня есть массив 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 ]

2 голосов
/ 22 октября 2011

Здесь все в порядке. Дьявол кроется в деталях. Понятно, что это не настоящий код, а ваша сводка кода, поэтому вы случайно что-то исправили, суммируя его. Наиболее вероятная проблема, с которой вы столкнулись, заключается в том, что сериализация Java по умолчанию записывает данный объект в поток только один раз; так что если вы напишите массив, измените содержимое и напишите его снова, второй экземпляр будет передан по проводам как просто ссылка на первый с первым набором значений. Клонирование массива в конструкторе «пакетов», как уже упоминал кто-то, определенно поможет!

1 голос
/ 08 апреля 2012

Мне очень нравится вопрос, он мне очень помог.Я просто хочу добавить некоторые вещи, которые я только что выучил для полноты.

  • Ответ 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. повторить, начиная с 3, если не выполнено

Я лично использую эти шаги для многократного изменения игрового поля сетевой игры и отправки правильных данных клиентам.

1 голос
/ 22 октября 2011

Вы сэкономите около 90% требований к пространству сериализации, если создадите массив int[] вместо Integer[].Кроме этого, нет никаких причин, по которым ваш код не будет работать правильно, если вы понимаете, для чего ObjectOutputStream.reset()/writeUnshared().

Кроме того, тестирование результата readObject() для null не имеет смысла, если вы не планируетеотправить нули.Он не возвращает NULL в EOS, так как многие люди сначала приходят к выводу: он вызывает исключение EOFException.

1 голос
/ 22 октября 2011

Не думаю, что это хорошая идея:

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...