2013-04-11 2 views
2

Я пытаюсь поместить объекты (Lieu) в ArrayList, но в конце кода мой список по-прежнему пуст. Я искал в сети ответ, но все, что я нахожу, это «Напишите свои объекты в коллекции, а затем прочитайте коллекцию». Но файл уже написан, и мне нужно найти способ поместить все объекты (Lieu) в ArrayList.Не удается прочитать несколько объектов из файла

Вот написание кода (я не могу изменить его):

public static void main(String[] args) { 
     Lieu<Double, String> p1; 
     Lieu<Double, String> p2; 
     Lieu<Double, String> p3; 
     SegmentGeo<String> e1; 
     SegmentGeo<String> e2; 
     SegmentGeo<String> e3; 
     Parcelle<String> p = new Parcelle<String>(); 
     ArrayList<Mesure<Point<Double>, String>> segs; 
     p1 = new Lieu<Double, String>(45.573715, -73.900295, "p1"); 
     p2 = new Lieu<Double, String>(45.573882, -73.899748, "p2"); 
     p3 = new Lieu<Double, String>(45.574438, -73.900099, "p3"); 
     e1 = new SegmentGeo<String>(p1, p2, "Parcelle test"); 
     e2 = new SegmentGeo<String>(p2, p3, "Parcelle test"); 
     e3 = new SegmentGeo<String>(p3, p1, "Parcelle test"); 
     segs = new ArrayList<Mesure<Point<Double>, String>>(); 
     segs.add(e1); 
     segs.add(e2); 
     segs.add(e3); 
     try { 
      p.setMesures(segs); 
     } catch (TrajectoireNonValideException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     ObjectOutputStream ois = null; 
     try { 
      ois = new ObjectOutputStream(new FileOutputStream("essai.txt")); 
      ois.writeObject(p.informationCumulee()); 
      ois.writeObject(p1); 
      ois.writeObject(p2); 
      ois.writeObject(p3); 
     } catch (EOFException ex) { 
      System.out.println("Fin de fichier atteinte."); 
     } catch (FileNotFoundException ex) { 
      ex.printStackTrace(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } finally { 
      try { 
       if (ois != null) { 
        ois.close(); 
       } 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 

И вот что я пытаюсь сделать:

public void actionPerformed(ActionEvent arg0) { 
    JFileChooser chooser = new JFileChooser(); 
    int retour = chooser.showOpenDialog(getParent()); 
    if(retour==JFileChooser.APPROVE_OPTION){ 
      try{ 
     FileInputStream fis = new FileInputStream(chooser.getSelectedFile().getName()); 
     ObjectInputStream ois = new ObjectInputStream(fis); 
     champNom.setText((String) ois.readObject());//that's just to display the name 
     while (ois.available()!=0) 
     { 
      temp = (Lieu)ois.readObject(); 
      l.add(temp); 
     } 
     ois.close(); 
     System.out.print(l.size());//The size is 0 
     } 
     catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
     catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

ответ

1

Как говорит Joetjah, available() не работает, как это звучит.

Одно из решений, не супер элегантный, но работает на удивление хорошо, чтобы просто поймать Exception S, который будет брошен, когда нет ничего, чтобы читать или другое исключение, как таковой:

try { 
     while (true) 
      l.add((Lieu<Double,String>)ois.readObject()); 
    } catch (ClassNotFoundException | IOException e) { 
     //Expecting a EOFException here 
    } finally { 
     try { 
      ois.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

Всякий раз, когда есть более исключение бросается при чтении (и в какой-то момент будет один!), он перестанет читать.

+0

Да, это работает! большое спасибо –

0

Available doesn't do what you think it does

доступны() делает не возвращать объем данных, подлежащих чтению, а объем данных, которые можно читать без блокировки (приостановка для ожидания получения большего количества данных из файла/сокета/базы данных и т. д.). В некоторых случаях это может возвращать ноль, в то время как все еще есть байты, которые должны быть прочитаны - 0 означает, что сейчас есть 0 байтов (без блокировки). Это может произойти по разным причинам: жесткий диск может быть занят перестановкой своего магнитофона или сетевое соединение может быть занято или, возможно, вы ждёте, когда пользователь где-то напечатает что-нибудь, прежде чем их информация может быть отправлена. Или это может быть из-за того, что в файле, который вы читаете, нет дополнительных байтов для чтения, потому что вы достигли конца. Используя доступные(), у вас нет способа узнать, следует ли вообще пытаться читать байты.

Более правильный способ использовать поток, чтобы скопировать файл, чтобы проверить возвращаемое значение чтения для значения конца-файла (-1):

InputStream is = // some input 
OutputStream os = // some output 
byte buffer = new byte[1024]; 
int bytesRead; 
while ((bytesRead = is.read(buffer)) != -1) { 
    os.write(buffer, 0, bytesRead); 
} 

Когда этот код завершает, вы знайте, что все байты действительно были прочитаны и скопированы, потому что цикл while не завершается, пока read() не возвращает -1, что указывает на конец ввода.

Теперь, в вашем случае, я бы посоветовал взять его в какой-то другую сторону, как это:

FileInputStream fis = new FileInputStream(chooser.getSelectedFile().getName()); 
ObjectInputStream ois = new ObjectInputStream(fis); 
Object obj = ois.readObject(); 
while (obj != null) 
{ 
    champNom.setText((String)obj); 

    if (obj instanceof Lieu<Double, String>) 
     l.add(obj); 

    obj = ois.readObject(); 
} 
ois.close(); 
System.out.print(l.size()); 
+0

Это проблематично. Прежде всего, ваш совет в этом случае не может быть скомпилирован по нескольким причинам, но также и с ошибкой ИМО. Нуль-проверка ничего не делает, кроме проверки нуль-объектов. Если в файле OPs находится файл Lieu, он не сможет прочитать остальную часть файла. Это приведет к исключению EOFException в конце. – ddmps

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