ByteArrayInputStream to ObjectInputStream исчезли

У меня есть кое-что, чего я не понимаю, пожалуйста, помогите.

System.out.println("\n" + Arrays.toString(buffer) + "\n");
System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available());
ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(buffer));
System.out.println("input.available(): " + input.available());

Его вывод ниже:

[-84, -19, 0, 5]

buffer.length = 4
new ByteArrayInputStream(buffer).available() is: 4
input.available(): 0

Я так запутался, почему байтовый массив из 4 действительных байтов после помещения в ObjectInputStream становится равным нулю.

Вещи, которые я пробовал:

  1. Изначально я сомневался, что мой байтовый массив пуст, но, как вы видите, я распечатал, его длина равна 4.
  2. Затем я подумал, что мой байт может быть недействительным, поэтому я распечатал каждый байт, как вы видите, все эти четыре байта являются действительными.

Итак, я заблудился, почему это происходит.

Пожалуйста, помогите, большое спасибо!

2 ответа

Решение

Как уже упоминалось в другом ответе, available означает только количество байтов, которые вы можете прочитать до блокировки.

Однако я полагаю, что вы не следовали правилам ObjectInputStreamкоторые указывают An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.

Другими словами, для того, чтобы фактически прочитать данные с ObjectInputStreamсначала вы должны были записать данные, используя ObjectOutputStream какой-то Вот пример, показывающий это с предоставленными вами данными:

byte[] buffer = new byte[]{-84,-19,0,5};
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream= new ObjectOutputStream(out);
objectOutputStream.write(buffer);
objectOutputStream.flush();

ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
System.out.println("input.available(): " + input.available());
System.out.println("input.readByte(): " + input.readByte());

(Я добавлю, что я очень редко работаю с IO в Java, поэтому вышеупомянутое не может быть лучшей практикой или иметь лишний код.)

Здесь находится Javadoc available метод, и это то, что он говорит:

Возвращает количество байтов, которые могут быть прочитаны без блокировки.

Таким образом, он не возвращает общее количество bytes присутствует в вашем массиве / чтения, он возвращает количество bytes он может читать, прежде чем заблокирован. Таким образом, возвращение 0 является допустимым сценарием.

Теперь давайте посмотрим на javadoc ObjectInputStream, вот краткое объяснение:

Необъектные чтения, которые превышают конец выделенных данных, будут отражать конец данных точно так же, как они указывали бы на конец потока: побитовые чтения вернут -1 как чтение байтов или число прочитанных байтов, и примитив читает выбросит EOFExceptions. Если соответствующего метода writeObject нет, то конец сериализованных данных по умолчанию отмечает конец выделенных данных.

То, что вы пытаетесь сделать в своем коде, это read примитивные данные (или чтение без WriteObject метод), так как это недействительные данные (для ObjectInputStream) read всегда будет возвращать -1. И я смог воспроизвести EOFExceptionпросто позвонив readObject метод.

Затем я попытался написать / прочитать новый объект и проверил available вызов метода, посмотрите на приведенный ниже фрагмент кода:

byte[] buffer = new byte[]{-84, -19, 0, 5};
System.out.println("\n" + Arrays.toString(buffer) + "\n");
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer);
System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available());
ObjectInputStream input = new ObjectInputStream(byteArrayInputStream);
System.out.println("input.available(): " + input.available());
//      System.out.println(input.readObject()); //Uncomment to see EOFException

Date date = new Date();
System.out.println(date);
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteArrayOut);
out.writeObject(date);
byte[] bytes = byteArrayOut.toByteArray();

input = new ObjectInputStream(new ByteArrayInputStream(bytes));
System.out.println(input.available());
System.out.println(input.readObject());

Код reads уже записанный объект и печатает значение. Обратите внимание, что даже если он правильно читает объект и печатает тот же объект, available Метод по-прежнему возвращает 0. Итак, я бы рекомендовал не слишком полагаться на available из-за вводящего в заблуждение названия:)

Другие вопросы по тегам