ObjectInputStream не имеет доступных байтов после создания с помощью ByteArrayInputStream
Я создаю класс, который обрабатывает двоичную де / сериализацию. Метод open()
получает InputStream
и OutputStream
, Те созданы другим open()
метод, который получает путь в качестве аргумента. InputStream
на самом деле ByteArrayInputStream
, Я уже сделал несколько тестов, чтобы доказать, что InputStream
прибывает в open()
метод с содержанием - и это на самом деле. Но когда я пытаюсь установить ObjectInputStream
используя это, это не работает. Не выдается никаких исключений, но когда я пытаюсь прочитать из него байты, это всегда дает мне -1
,
Класс BinaryStrategy
public class BinaryStrategy implements SerializableStrategy{
public BinaryStrategy(){
try{
open("products.ser");
}catch(IOException ioe){
}
}
@Override
public void open(InputStream input, OutputStream output) throws IOException {
try{
this.ois = new ObjectInputStream(input);
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
@Override
public void writeObject(fpt.com.Product obj) throws IOException {
oos.writeObject(obj);
oos.flush();
}
@Override
public Product readObject() throws IOException {
Product read = new Product();
try{
read.readExternal(ois);
}catch(IOException | ClassNotFoundException exc){
System.out.println(exc);
}
return read;
}
}
интерфейс SerializableStrategy (просто метод по умолчанию)
default void open(Path path) throws IOException {
if (path != null) {
ByteArrayInputStream in = null;
if (Files.exists(path)) {
byte[] data = Files.readAllBytes(path);
in = new ByteArrayInputStream(data);
}
OutputStream out = Files.newOutputStream(path);
open(in, out);
}
Класс продукта
public class Product implements java.io.Externalizable {
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeLong(getId());
out.writeObject(getName());
out.writeObject(getPrice());
out.writeObject(getQuantity());
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.setId((Long)in.readLong());
this.setName((String) in.readObject());
this.setPrice((Double) in.readObject());
this.setQuantity((Integer) in.readObject());
}
Я должен был персонализировать это, потому что атрибуты SimpleProperty
s
В public void open(InputStream input, OutputStream output)
Я попытался сделать некоторые вещи, как следует, чтобы проверить:
public void open(InputStream input, OutputStream output) throws IOException {
try{
System.out.println(input.available() + " " + input.read() + " " + input.read());
//is gives me: 181 172 237
//181 is the exact size of the file I have, so i think that the Output is ok
//172 237 - just some chars that are in the file
//I know that for now on it is going to give me an excepetion because
// of the position of the index that is reading. I did it just to test
this.ois = new ObjectInputStream(input);
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
А потом другой тест:
public void open(InputStream input, OutputStream output) throws IOException {
try{
this.ois = new ObjectInputStream(input);
System.out.println(ois.available() + " " + ois.read());
//here is where I am receiving -1 and 0 available bytes!
//so something is going wrong right here.
//i tried to just go on and try to read the object,
//but I got a EOFException, in other words, -1.
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
3 ответа
ObjectInputStream
внутренне использует BlockDataInputStream
выполнить свои операции чтения. Это читает блок данных, а не просто байт, как мы ожидаем, когда вы вызываете read
, Он читает байт, только если он падает как "блок"
Вывод не то, что я ожидал. Но, если вы посмотрите на код ObjectInputStream.read()
, это имеет смысл.
Итак, в вашем случае имеет смысл использовать только readObject
восстановить состояние ваших объектов.
Вот ваш код снова...
class SimpleJava {
public static void open(InputStream input, OutputStream output) throws IOException {
try {
ObjectInputStream ois = new ObjectInputStream(input);
System.out.println(ois.available());// 0
System.out.println(ois.available() + " " + ois.read() + " " + ois.read());// 0 -1 -1
// Reads the object even if the available returned 0
// and ois.read() returned -1
System.out.println("object:" + ois.readObject());// object:abcd
}
catch (Exception ioe) {
ioe.printStackTrace();
}
}
static void open(Path path) throws IOException {
if (path != null) {
ByteArrayInputStream in = null;
if (Files.exists(path)) {
byte[] data = Files.readAllBytes(path);
in = new ByteArrayInputStream(data);
}
OutputStream out = Files.newOutputStream(path);
open(in, out);
}
}
public static void main(String[] args) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/home/pradhan/temp.object")));
oos.writeObject("abcd");//writes a string object for us to read later
oos.close();
//
open(FileSystems.getDefault().getPath("/home/user/temp.object"));
}
}
Вот выход...
0
0 -1 -1
object:abcd
Пожалуйста, проверьте, если файл представлен path
имеет объект Java, записанный в него.
Из документа API ObjectInputStream https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html
ObjectInputStream десериализует примитивные данные и объекты, ранее написанные с использованием ObjectOutputStream.
ObjectInputStream используется для восстановления этих объектов, ранее сериализованных.
Если вы делаете this.ois.readObject()
и вы получаете -1
, есть вероятность, что файл не содержит объекта в нем.
Обновить: readObject
возвращает объект, а не int
, Если вы используете read
методы в ois
и вы получаете -1
, то файл пуст.
Кроме того, есть вероятность, что ваш файл содержит -1 в качестве содержимого;)
Проблема заключалась в том, что я читал ObjectInputStream
неправильный путь. Это было как:
read.readExternal(ois);
но правильный путь:
read = (Product)ois.readObject();
И из-за исключений, которые я получал за это, я подумал, что проблема была в строительстве ObjectInputStream
когда используешь ByteArrayInputStream
, Какая большая ошибка!:D
Спасибо всем, кто пытался помочь.