2015-04-18 2 views
3

Я работаю над проектом Java, который использует Apache POI для управления файлами .docx. Два дня назад у меня возникла проблема, которую я не смог решить. Я действительно не знаю, где моя ошибка, и что ее вызывает. Единственное, что я знаю, это то, что делает ошибка.Бесконечный цикл while с итератором hasNext() и next()

Два дня назад все работало нормально. Я выбрал свой .docx, нажал на переключатели, которые определяют, какие изменения будут выполнены, а затем я нажал кнопку «отправить», чтобы начать эту работу. Он работал следующим образом: Получите весь текст из .docx с помощью методов POI Apache, проведите по каждому прогону, измените ключевое слово и грамматику и поместите обновленный Paragraph с его результатами обратно в документ. Этот процесс повторяется для изменений со второго переключателя. Наконец, документ с изменениями с обоих переключателей сохраняется с суффиксом в имени файла. Если я сейчас выбираю один специальный переключатель, то манипуляция выполняется успешно через весь документ. Но затем, во время манипуляции с вторым прогоном (который определяется вторым переключателем), похоже, что выполнение зависает в определенной точке, потому что консоль Eclipse не показывает никаких изменений. На самом деле, если я завершаю приложение и заглядываю в результирующий документ, я увижу, что тот же фрагмент текста снова и снова вставляется в документ. Документ составляет около 11 страниц. Это баггинское вложение увеличивает его размер более чем на 330 страниц за несколько секунд. Это заставляет меня думать, что должен быть бесконечный цикл. Что-то еще не имеет для меня никакого смысла.

Странно, что я никогда ничего не менял по этому алгоритму (я думаю). Одна из последних вещей, которые я делал, - это обновление моей версии Java до 8u45, но поскольку я вернулся к своей предыдущей версии, и ошибка все еще сохраняется, я не похожа на то, что обновление вызвало ошибку.

Надеюсь, у одного из вас, у вас, есть совет для меня. Я не думаю, что размещение моего кода здесь полезно, потому что это почти полная копия других методов, которые работают нормально, но я сделаю это в любом случае. Этот мир кода является единственной частью (после выбора переключателя с багги), где я использую цикл while. Все остальные петли предназначены для циклов. Что меня смущает:

  • Что такое первый радиальный звук (глючный), так что выполнение следующего изменения заканчивается бесконечным циклом?
  • Если это цикл ввода, как он записывается в моем документе? Как вы видите, я пишу только текст в документе, когда я оставляю цикл while. Когда я заканчиваю его вручную в Eclipse, в документе не должно быть никакого текста.

    public static void changeSingleMaleToMultiMale(String path, String title, XWPFDocument document) throws Exception 
    { 
        XWPFDocument oldDoc = document; 
        Iterator<XWPFParagraph> iterator = document.getParagraphsIterator(); 
        int length = title.length(); 
    
        int counter = 0; 
    
        while(iterator.hasNext()) 
        { 
         XWPFParagraph paragraph = iterator.next();    
         System.out.println("____ unchanged\n" + paragraph.getText() + "\n____\n\n"); 
    
         List<XWPFRun> runs = paragraph.getRuns(); 
    
    
         for(int i = 0; i < runs.size(); i++) 
         { 
          String text = runs.get(i).toString(); 
    
    
          if(text.contains(title)) 
          { 
           runs.get(i).setText(StringFunctions.fromSingleMaleToMultiMale(text, title, length), 0); 
          } 
         } 
         System.out.println("____ updated\n" + paragraph.getText() + "\n____\n\n"); 
         document.setParagraph(paragraph, counter); 
         counter++; 
        } 
    
        try { 
    
         FileOutputStream output = new FileOutputStream(path.substring(0, path.length()-5) + "Aktualisiert.docx"); 
         document.write(output); 
         output.close(); 
        } catch (FileNotFoundException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
    } 
    

Кто-нибудь испытал что-то подобное? Я был бы рад за каждый маленький намек на это.

ОБНОВЛЕНИЕ: код ошибки, вызываемый путем выбора упомянутого переключателя, не влияет на методы, вызываемые другими переключателями. Это похоже на это. На самом деле глючный мир кода пишет такой огромный текст в мою переменную, и в этот момент я думаю, что поток вывода все еще занят написанием огромного текста в моем документе, в то время как следующие методы пытаются получить доступ к документу. Пока что это отвечает на первый вопрос из списка выше. Другой вопрос и проблема все еще остаются открытыми.

+0

TLDR; Что говорит отладчик? – talex

+0

Хорошая идея, дайте мне несколько минут, чтобы проверить это. Я еще не использовал отладчик, потому что у меня есть куча printlns, которая дала мне подробную информацию о каждом шаге в коде ... ну, с тех пор. – KJaeg

+0

У вас есть все время вселенной :) – talex

ответ

1

Несколько дней назад я нашел решение для этого.

Не было бесконечного цикла, даже если он выглядит так, потому что один и тот же текст вклеился тысячи раз в мой документ.

После некоторого отчаянного времени, пытаясь выяснить, почему моя петля работает неправильно, я решил проглотить горькую таблетку и попытаться выяснить шаг за шагом, что вызывает ошибку.

Таким образом, я поместил большую часть кода в комментарии и раскомментировал каждый фрагмент кода, шаг за шагом. Я узнал, что цикл был правильно реализован, и ошибка была скрыта в методе, который помогает заменить некоторый текст в документе.

я получил что-то вроде этого:

String checkString = ""; 

как простой начального значения для моей переменной.

В некоторых особых случаях «checkString» получит строку, в некоторых других случаях она должна быть оставлена ​​пустой строкой.

Ошибка при обработке второго корпуса. У меня есть предложение, если, который определяется так:

if(baseString.contains(checkString)) 

вы видите здесь, что может произойти, если «checkString» пустая строка? Да, конечно, «baseString» содержит «», в любом случае. Это условие if-true было истинным, каждый раз. Другие строки в этом if-clause сделали некоторую работу, что привело к тому, что выглядит как бесконечное вложение текста.

if(checkString != "" && baseString.contains(checkString)) 

исправлено все.

То, как проявилась ошибка, побудило меня думать, что ошибка была повсюду, но не в этом методе. Забавно, как эти простые ошибки заставляют меня так злиться.

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