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

感謝大家試圖幫助。

相關問題