2015-04-24 4 views
2

Я использую Stream API, представленный на Java 8, для запуска метода для каждой строки в списке.Необработанное IOException внутри Java List.stream.forEach Lambda Expression

public boolean initFile() throws IOException 
{ 
    if (this.outFile.exists()) { 
     this.outFile.delete(); 
    } 
    return this.outFile.createNewFile(); 
} 

public void writeStringToFile(String str, boolean addNewLine) throws IOException 
{ 
    if (this.mode != FileMode.READ) { 
     if (this.initFile()) { 
      FileWriter fileWriter; 
      if (this.mode == FileMode.APPEND) 
       fileWriter = new FileWriter(outFile.getAbsolutePath(), true); 
      else 
       fileWriter = new FileWriter(outFile.getAbsolutePath()); 
      fileWriter.write(str); 
      if (addNewLine) 
       fileWriter.write("\n"); 
      fileWriter.close(); 
     } else { 
      throw new IOException("IO Error: The file could not be initialized."); 
     } 
    } else { 
     throw new IOException("Cannot write to a file with the mode FileMode.READ"); 
    } 
} 

public void writeListToFile(List<String> strings, boolean addNewLine) throws IOException 
{ 
    strings.stream().forEach(s -> this.writeStringToFile(s, addNewLine)); // Unhandled IOException from writeStringToFile 
} 

Как вы можете видеть, метод сигнатур состояний бросить все IOExceptions и метод writeToString внутри потока имеет потенциал, чтобы бросить IOException. Однако компилятор Java дает мне ошибку, заявляя, что в потоковой линии есть необработанное исключение IOException.

Почему исключение внутри потока не может быть выбрано как любое другое исключение внутри метода? Есть ли способ, которым я могу исправить это, не помещая инструкцию try-catch в выражение forEach лямбда?

+2

Что вы хотите, если вы выбрали IOException? Обратите внимание, что это мало связано с лямбдами и довольно регулярными правилами исключения. 'Stream # forEach' и' Customer # accept' не объявляют об отказе от этого исключения. – Radiodef

+0

Можете ли вы обновить свой вопрос с помощью объявления метода initFile – Sarkhan

+0

Я добавил метод initFile. Обратите внимание, что все IOExceptions выбрасываются намеренно по дизайну. –

ответ

2

вы должны использовать попробовать поймать в вас writeListToFile метод, как это:

public void writeListToFile(List<String> strings, boolean addNewLine) throws Exception { 
    strings.stream().forEach(s -> { 
     try { 
      writeStringToFile(s, addNewLine); 
     } catch (IOException ex) { 
      //you can Log it immediately or throw ex; 
      Logger.getLogger(C.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    }); 
    // Unhandled IOException from writeStringToFile 
} 

почему? взгляд на эту точку s -> {} .Здесь {} означает, что компилятор делает новый интерфейс (Consumer)

void forEach(Consumer<? super T> action); 

и новый класс реализует этот интерфейс и передать параметр в сек это принять method.Can вы бросаете исключение из новый класс в вашем методе? Нет. Нужно попробовать уловить каждый предмет foreach.

+0

У меня очень наивное понимание Stream API в целом. Кажется, вы знаете о базовых процессах, которые для меня немного черная. У вас есть хорошие, непрофессиональные ресурсы для потребителей/поставщиков/предикатов/и т. Д.? –

+0

google new in java 8.read subjects.research, что вы застряли, и написать блог, чтобы полностью понять. Когда вы пишете блог, вам придется учить кого-то и знать предмет намного понятнее – Sarkhan

3

Не изобретайте велосипед. Используйте функции, предлагаемые Java API.

public void writeListToFile(List<String> strings, boolean addNewLine) throws IOException 
{ 
    if(this.mode == FileMode.READ) 
     throw new IOException("Cannot write to a file with the mode FileMode.READ"); 

    Files.write(outFile.toPath(), addNewLine? strings: 
     Collections.singleton(strings.stream().collect(Collectors.joining())), 
    this.mode==FileMode.APPEND? StandardOpenOption.APPEND: StandardOpenOption.CREATE); 
} 

Files.write будет записывать все строки с Iterable (который включает в себя Collection с), и это все. Ваше препятствие для поддержки опции addNewLine можно решить, собирая все String s в один в случае, addNewLine - false, следовательно, между ними не будет линий. В противном случае Files.write будет добавлять строки к каждой строке.

Нет смысла вручную проверять наличие файлов или пытаться их удалить или создать. Независимо от того, создаете ли вы свой собственный или используете Files.write, эти реализации будут сообщать о сбоях в отношении существования/небытия или неудачных попытках создания целевого файла через IOException, так что вам не нужно делать это самостоятельно.

Еще хуже то, что File.exists(), File.delete(), или File.createNewFile() может вернуться, уже является устаревшей информацией о вашей последующей операции ввода-вывода, например. создание/использование Writer и не гарантирует ничего о том, будет ли последующая операция успешной или неудачной.