0

Je construis une classe qui gère un De Binary/Serialization. La méthode open() reçoit un InputStream et un OutputStream. Ceux-ci sont créés par une autre méthode open() qui reçoit un chemin en tant qu'argument. Le InputStream est en fait un ByteArrayInputStream. J'ai déjà fait quelques tests pour prouver que le InputStream arrive à la méthode open() avec du contenu - et c'est effectivement le cas. Mais quand j'essaye de mettre un ObjectInputStream en l'employant, cela ne fonctionne pas. Aucune exception n'est levée, mais quand j'essaie de lire des octets, cela me donne toujours -1.ObjectInputStream n'a pas d'octets disponibles après avoir été construit avec un ByteArrayInputStream

classe 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 d'interface (seulement la méthode par défaut)

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

Classe de produit

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

je dû personnaliser parce que les attributs sont SimpleProperty s

A public void open(InputStream input, OutputStream output) j'ai essayé de faire des choses comme suit pour tester:

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

Et puis l'autre test:

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

nous dans le reste du code, il n'y a rien que nous pouvons faire avec seulement ce que je –

+0

édité maintenant. –

+0

s'il vous plaît nous montrer le code où vous obtenez -1 également –

Répondre

0

ObjectInputStream, utilise en interne un BlockDataInputStream pour effectuer ses opérations de lecture. Cela lit un bloc de données et pas seulement un octet comme on s'y attend, lorsque vous appelez un read. Il lit un octet seulement s'il tombe comme un "bloc"

La sortie n'est pas ce que j'attendais non plus. Mais, si vous regardez le code de ObjectInputStream.read(), il est logique. Donc, dans votre cas, il est logique d'utiliser seulement readObject pour restaurer l'état de vos objets.

Heres à nouveau votre code ...

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

Heres la sortie ...

0 
0 -1 -1 
object:abcd 
2

S'il vous plaît vérifier si le fichier représenté par le path a un objet Java écrit dessus.
De l'API ObjectInputStream doc https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html

Une ObjectInputStream désérialise données primitives et des objets précédemment écrits en utilisant un ObjectOutputStream. ObjectInputStream est utilisé pour récupérer les objets précédemment sérialisés.

Si vous faites un this.ois.readObject(), et vous obtenez un -1, il y a des chances que le fichier ne contient pas un objet en elle.

Mise à jour: readObject renvoie un objet et non un int. Si vous utilisez les méthodes read dans ois et que vous obtenez un -1, le fichier est vide.

En outre, il y a des chances que votre fichier contient -1 comme son contenu;)

+0

Merci pour la réponse! Mais j'ai utilisé 'ObjectOutputStream' pour écrire le fichier que j'essaie de désérialiser, donc le fichier doit contenir un objet sérialisé. Comme je l'ai dit, 'OutputStream', qui est en fait un' ByteArrayOutputStream', transporte quelque chose. J'ai utilisé les méthodes 'available()' et 'read()' pour le prouver et cela fonctionne réellement. –

+0

Je vois que vous lisez l'objet à partir du 'path' et que vous ouvrez un' newOutputStream' sur le même 'chemin'. Notez que cela effacera le fichier. Vérifiez si vous avez des exceptions pendant que vous écrivez dans le fichier. –

+0

Pouvez-vous poster le code utilisé pour lire l'objet? –

0

Le problème était que je lisais le ObjectInputStream dans le mauvais sens.Il était comme:

read.readExternal(ois); 

mais la façon correcte est:

read = (Product)ois.readObject(); 

Et beacause des exceptions que je recevais de le faire, je pensais que le problème était avec la construction de ObjectInputStream lors de l'utilisation ByteArrayInputStream . Quelle grosse erreur! : D

Merci à tous ceux qui ont essayé de vous aider.