java - 使用 ByteArrayInputStream 构造 ObjectInputStream 后没有可用字节

标签 java serialization inputstream objectinputstream bytearrayinputstream

我正在构造一个处理二进制反/序列化的类。 open() 方法接收一个 InputStream 和一个 OutputStream。它们是由另一个接收路径作为参数的 open() 方法创建的。 InputStream 实际上是一个ByteArrayInputStream。 我已经做了一些测试来证明 InputStream 正在到达带有内容的 open() 方法 - 事实上它确实如此。但是当我尝试使用它设置 ObjectInputStream 时,它不起作用。没有抛出异常,但是当我尝试从中读取字节时,它总是给我 -1

BinaryStrategy class

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;
  }
}

interface SerializableStrategy (just the default method)

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

Product class

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());
}

我必须对其进行个性化,因为属性是 SimplePropertys

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

最佳答案

请检查path表示的文件是否写入了java对象。
来自 ObjectInputStream API 文档 https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html

An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.

ObjectInputStream is used to recover those objects previously serialized.

如果您正在执行 this.ois.readObject(),并且得到 -1,则该文件很可能不包含以下对象:它。

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

此外,您的文件的内容可能包含 -1 ;)

关于java - 使用 ByteArrayInputStream 构造 ObjectInputStream 后没有可用字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37227965/

相关文章:

java - 我如何使用这个新的监听器

java - 适用于 Android 的 Swing 库?

django-rest-framework - 在通过 SerializerMethodField 调用的方法中传递参数

c# - WCF 中的动态对象不可能吗?

java - 资源应该关闭 - Sonar

c++ - C++中的插入器和提取器函数

java - 在 arangoDB 的 java 驱动程序中绑定(bind)集合

java - 如何在 Java 中比较字符串?

c# - 如何在 .NET 远程处理期间使用自定义序列化?

database - 从数据库中读取 HTML 数据很慢?需要更好的方法吗?