0

我在构造一个处理Binary De/Serialization的类。方法open()收到InputStreamOutputStream。这些是由接收路径作为参数的另一个open()方法创建的。 InputStream实际上是一个ByteArrayInputStream。 我已经做了一些测试,证明InputStream到达open()方法与内容 - 实际上是。但是当我尝试设置使用它的ObjectInputStream时,它不起作用。没有例外,但是当我尝试从它读取字节时,它总是给我-1ObjectInputStream在用ByteArrayInputStream构造之后没有可用的字节

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小号

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); 
} 
+0

向我们展示的代码的其余部分,我们没有什么可以只用这个 –

+0

我做编辑它现在。 –

+0

请告诉我们你得到的代码-1也 –

回答

0

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 
2

请检查代表的文件有一个写入它的java对象。
从ObjectInputStream的API文档https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html

的ObjectInputStream的反序列化基本数据和对象先前使用ObjectOutputStream写入。

ObjectInputStream用于恢复先前序列化的对象。

如果你正在做一个this.ois.readObject(),和你得到一个-1,还有一些文件不包含在一个对象的机会。

更新:readObject返回一个对象而不是int。如果您在ois中使用read方法,并且您获得-1,则该文件为空。

此外,还有一些文件包含-1作为其内容的机会;)

+0

谢谢你的答案!但是我使用'ObjectOutputStream'来编写我想要反序列化的文件,所以文件必须包含一个序列化的对象。正如我所说的,'OutputStream',实际上是一个'ByteArrayOutputStream',它携带着一些东西。我使用'available()'和'read()'方法来证明它并且它实际上起作用。 –

+0

我看到你正在从'path'读取对象,并在同一''path'上打开'newOutputStream'。请注意,这将清除文件。 检查在写入文件时是否收到异常。 –

+0

你可以发布用于阅读对象的代码吗? –

0

的问题是,我正在读ObjectInputStream走错了路。它是这样的:

read.readExternal(ois); 

,但正确的做法是:

read = (Product)ois.readObject(); 

而且东阳我正在这样做的例外,我以为问题使用ByteArrayInputStream时用的ObjectInputStream建设。 真是个大错! :D

感谢大家试图帮助。

相关问题