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 становится равным нулю.
Вещи, которые я пробовал:
- Изначально я сомневался, что мой байтовый массив пуст, но, как вы видите, я распечатал, его длина равна 4.
- Затем я подумал, что мой байт может быть недействительным, поэтому я распечатал каждый байт, как вы видите, все эти четыре байта являются действительными.
Итак, я заблудился, почему это происходит.
Пожалуйста, помогите, большое спасибо!
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
из-за вводящего в заблуждение названия:)