2010-05-26 2 views
1

Я пишу небольшую программу на Java (это плагин ImageJ, но проблема не связана именно с ImageJ), и у меня есть некоторые проблемы, скорее всего из-за того, что я никогда не программировал на Java до ...Чтение сериализованного объекта из файла

Итак, у меня есть вектор векторов, и я пытаюсь сохранить его в файле и прочитать его.

переменная определяется как:

Vector <Vector <myROI> > ROIs = new Vector <Vector <myROI> >(); 

, где myROI это класс, который я определено ранее.

Теперь, чтобы записать вектор в файл я использую:

void saveROIs() 
    { 
    SaveDialog save = new SaveDialog("Save ROIs...", imp.getTitle(), ".xroi"); 
    String name = save.getFileName(); 
    if (name == null) 
     return; 
    String dir = save.getDirectory(); 

    try 
     { 
     FileOutputStream fos = new FileOutputStream(dir+name); 
     ObjectOutputStream oos = new ObjectOutputStream(fos); 
      oos.writeObject(ROIs); 
      oos.close(); 
     } 
    catch (Exception e) 
     { 
     IJ.log(e.toString()); 
     } 
    } 

Это правильно генерирует двоичный файл, содержащий (я полагаю) объект ROIs.

Теперь я использую очень похожий код для чтения файла:

void loadROIs() 
    { 
    OpenDialog open = new OpenDialog("Load ROIs...", imp.getTitle(), ".xroi"); 

    String name = open.getFileName(); 
    if (name == null) 
     return; 
    String dir = open.getDirectory(); 

    try 
     { 
      FileInputStream fin = new FileInputStream(dir+name); 
      ObjectInputStream ois = new ObjectInputStream(fin); 
     ROIs = (Vector <Vector <myROI> >) ois.readObject(); // This gives error 
      ois.close(); 
      } 
    catch (Exception e) 
     { 
     IJ.log(e.toString()); 
     } 
    } 

Но эта функция не работает.

Во-первых, я получаю предупреждение:

warning: [unchecked] unchecked cast found : java.lang.Object 
required: java.util.Vector<java.util.Vector<myROI>> 
      ROIs = (Vector <Vector <myROI> >) ois.readObject(); 
                 ^

Я гугле за что и посмотреть, что я могу подавить предваряя @SuppressWarnings("unchecked"), но это только делает вещи хуже всего, как я получаю сообщение об ошибке:

<identifier> expected 
    ROIs = (Vector <Vector <myROI> >) ois.readObject(); 
     ^

В любом случае, если я опускаю @SuppressWarnings и игнорировать предупреждение, объект не читается и исключение

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: myROI 

Снова Google сообщает мне, что myROI нуждается в implements Serializable. Я попробовал просто добавить implements Serializable к определению класса, но этого недостаточно. Может ли кто-нибудь дать мне несколько советов о том, как действовать в этом случае? Кроме того, как избавиться от предупреждения о методе?

+0

Что происходит после того, как вы добавили 'Serializable'? Вы перекомпилировали? – Bozho

+0

«этого недостаточно» - у вас все еще есть одно и то же исключение после того, как myROI реализует Serializable? BTW - соглашение об именовании! Названия классов начинаются с буквы верхнего регистра, переменные с нижним регистром (здесь: MyROI и rOI). Значительно увеличивает блаженство! –

+0

Да, я перекомпилировал, сохранил файл и попытался перезагрузить его, но я получаю ту же ошибку – nico

ответ

1
warning: [unchecked] unchecked cast found 

Это невинно и действительно должно быть исправлено с использованием аннотации @SuppressWarnings("unchecked").

<identifier> expected 

Это может быть вызвано добавлением аннотации. Вероятно, вы добавили его в неправильное место (должно быть правильно до объявления метода), или вы сделали что-то еще, из-за чего исчезла декларация ROIs.

java.io.NotSerializableException: myROI 

Это означает, что класс, идентифицированный данным полным классом, не является сериализуемым. Ожидайте, что это не сериализуемо, есть еще одна серьезная проблема: этот класс не находится внутри пакета. Это не обязательно является причиной текущей проблемы, но это может привести к будущим проблемам, поскольку классы пакетов не видны для классов внутри пакета.

Чтобы сделать сериализуемый класс, вы должны сообщить ему implements Serializable и убедиться, что все поля также сериализуемы. Примитивы по умолчанию сериализуются, и String сам уже реализует его, как вы можете прочитать в its Javadoc. Если поле действительно не может быть сделано сериализуемым по какой-либо причине, тогда вам необходимо объявить его transient и, если необходимо, переопределить private void readObject() и private void writeObject()accordingly, так что неэтериализуемый объект может быть записан/прочитан в пар в любом случае. По сути, вам просто нужно сохранить свое состояние каким-то образом, после чего точно такое же состояние может быть восстановлено.

E.g.

public class SerializableObject implements Serializable { 

    private transient UnserializableObject unserializableObject; 

    private void writeObject(ObjectOutputStream oos) throws IOException { 
     oos.defaultWriteObject(); 
     oos.writeObject(unserializableObject.getSerializableProperty()); 
     oos.writeObject(unserializableObject.getAnotherSerializableProperty()); 
     // ... 
    } 

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { 
     ois.defaultReadObject(); 
     unserializableObject = new UnserializableObject(); 
     unserializableObject.setSerializableProperty((SomeSerializableObject) ois.readObject()); 
     unserializableObject.setAnotherSerializableProperty((AnotherSerializableObject) ois.readObject()); 
     // ... 
    } 

} 
+0

Спасибо, я решил проблему '@ SuppressWarnings', это была просто глупая опечатка с моей стороны. : P Я думаю, что в этот момент мне нужно будет переопределить 'readObject' и' writeObject'. Для меня это не совсем понятно: в read/writeObject мне нужно называть 'writeObject' только для неэриализуемых свойств? 'defaultWriteObject()' относится к сериализуемым, не так ли? – nico

+0

Добро пожаловать. И нет, к сожалению, нет, вам действительно нужно включить ** все ** свойства, которые должны быть сериализованы. Поскольку этот метод является 'private', а API сериализации является синтаксическим сахаром, вы не можете называть нечто вроде' super.writeObject (oos) 'для покрытия отсутствующих, но сериализуемых свойств. – BalusC

+0

Спасибо, кажется, сейчас работает. – nico

1

Каждый атрибут myROI должен реализовывать Serializable или должен быть простым типом данных, таким как int. Это так?

+0

Хорошо, это, кажется, хороший момент. Некоторые из членов myROI - это классы ImageJ, не определенные мной. Как я могу реализовать «Serializable»? – nico

+0

Сначала вы должны проверить, нужно ли сериализовать эти атрибуты. Если нет, вы можете сделать их преходящими: «частный переходный процесс ImageJClass myimg;» В этом случае они не будут сериализованы, и поэтому не имеет значения, что они не являются Serializable. –

Смежные вопросы