2017-01-03 69 views
1

我有一小部分我已經做的代碼。我可能是錯的,但我相信我在所謂的staX(tbh,我不確定,我剛剛從一本隨機出版的書中學到了它)學到了它。它功能完好(至少它是,但我把我的數組列表變成了數組,而且我還沒有徹底測試擷取項目和neededitem部分,但他們似乎正在工作),但那些也不是我的主要焦點。我想知道是否有更好的方法(用staX)來重構我的代碼。我也試圖創建一個使用類來創建代碼的程序,所以我只需要經過它幾次,然後一切都被存儲,我可以使用這些,但爲了清晰起見,我做了不想要這個答案。我還注意到別的東西。當我運行程序時,它開始於11MB左右。它緩慢但肯定會收益。所以我不斷地運行輸入來查看會發生什麼,並且它會上升到大約500-550MB,並保持這個狀態。這是否意味着我忘了正確地關閉某些東西,或者只是預期並說,GC正在變慢?這聽起來確實不像這種情況,我覺得更像是我的錯。更好/更快的方式? java文本冒險與stax

我有一個主要的類,測試userInput,並一直運行,直到終止號碼,但這裏真的是唯一的東西,可能是重要的或有用的,據我所知。

currentGame.selectedOptionSetUp(userInputIntValue); 
currentGame.getOptions(); 
currentGame.printOptions(); 

對於我的代碼的主要部分。我很多if/else的確假設了預期的結果,而我在if裏面有一段時間的運行,直到返回true,我意識到這一點,我在其中一個else語句旁邊寫了一條評論。

同樣在我的代碼的某些部分,我認爲在一些嵌套語句中可能存在延遲的關閉方法,我相信如果它們被多次調用,沒有任何反應,所以我只是在我嘗試弄清楚是什麼讓程序能夠記住這麼多內容,我是否正確地認爲關閉方法可以被多次調用?

代碼:

public class TheGame { 

private int testAreaID; 
private int areaID = -1; 
private int sectorID= -1; 
private String areaDescription = ""; 
private String sectorDescription = ""; 
private String[] possibleOptions = new String[10]; 
private String[] newAreaOptions = new String[5]; 
private String[] descriptorOptions = new String[5]; 
private String[] userGainedItems = new String[10]; 
private String neededItem = null; 
private boolean optionRequiredItem= false; 
private boolean descriptorReqItem = false; 
private boolean areaReqItem = false; 
private String gainedItemText = null; 

private String gameFileName=""; 
private XMLInputFactory inputFactory = XMLInputFactory.newFactory(); 

public TheGame(String gameFile) 
{ 
    gameFileName = gameFile; 
    getIntro(); 
    printIntro(); 
    getOptions(); 
    printOptions(); 
} 

private void getIntro(){ 
    try{ 
     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 

     if(findIntro(gameFileXML)){   
      while(findEventLoc(gameFileXML,XMLStreamConstants.END_ELEMENT,"Intro")== false){ 
       if (gameFileXML.getEventType() == XMLStreamConstants.START_ELEMENT && !(gameFileXML.getLocalName().equals("Intro"))){ 
        String testString = gameFileXML.getLocalName(); 

        switch (testString){ 
         case "AreaID" : areaID = Integer.parseInt(gameFileXML.getElementText()); 
             break; 
         case "StartDescription" : areaDescription = gameFileXML.getElementText(); 
                break; 
         case "StartSector" : sectorID = Integer.parseInt(gameFileXML.getElementText()); 
        } 
       } 
       else gameFileXML.next(); 
      } 

     } 
      else gameFileXML.next(); 

     gameFile.close(); 
     gameFileXML.close(); 
     gameFile = null; 
     gameFileXML = null; 
    } 
    catch (IOException | XMLStreamException e){ 
     System.out.println(e); 
    } 
} // end of getIntro() method 

private void printIntro() 
{ 
    System.out.println(areaDescription + "\n"); 
    getSectorDescription(); 
    printSectorDescription(); 
} 

private void getSectorDescription() 

{ 
    try 
    { 
     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 
     completeBreak: 
     while(gameFileXML.hasNext()){ 
      if (findCorrectSector(gameFileXML)){ 
       while(gameFileXML.hasNext()){ 
        if(findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,"Description")){ 
         sectorDescription = gameFileXML.getElementText(); 
         break completeBreak; 
        } 
        else gameFileXML.next(); 
       } 
      } 
      else gameFileXML.next(); 
     } 

     gameFile.close(); 
     gameFileXML.close(); 
     gameFile = null; 
     gameFileXML = null; 
    } 

    catch (IOException | XMLStreamException e) 
    { 
     System.out.println(e); 
    } 
} 

private void printSectorDescription() 
{ 
    System.out.println(sectorDescription + "\n"); 
} // end of printSectorDescription() method 

public void getOptions() 
{ 
    try 
    { 
     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 

     if(findCorrectSector(gameFileXML)){ 
      while(gameFileXML.hasNext()){ 
       if(findEventLoc(gameFileXML,XMLStreamConstants.END_ELEMENT,"Sector")){ 
        gameFileXML.close(); 
        gameFile.close(); 
        break; 
       }   
       else if (findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,"Exit")){ 
        if((neededItem = returnAttData(gameFileXML,"ReqItem"))!= null){ 
         optionRequiredItem=true; 

        } 

        addToArray(possibleOptions,gameFileXML.getElementText()); 

        gameFileXML.next(); 
       } 
       else if (findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,"Leave")){ 
        if((neededItem = returnAttData(gameFileXML,"ReqItem")) != null){ 
         areaReqItem=true; 
        } 
        String areaOption = gameFileXML.getElementText(); 
        addToArray(possibleOptions,areaOption); 
        addToArray(newAreaOptions,areaOption); 
        gameFileXML.next(); 
       } 
       else if (findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,"Option")){ 
        if((neededItem = returnAttData(gameFileXML,"ReqItem")) != null){ 
         descriptorReqItem = true; 
        } 
        String descriptorOption = gameFileXML.getElementText(); 
        addToArray(possibleOptions,descriptorOption); 
        addToArray(descriptorOptions,descriptorOption); 
        gameFileXML.next(); 
       } 
       else gameFileXML.next();    
      } 
     }    
     gameFile.close(); 
     gameFileXML.close(); 
     gameFile = null; 
     gameFileXML = null; 

    } 
    catch (IOException | XMLStreamException e) 
    { 
     System.out.println(e); 
    } 
} 

public void printOptions() 

{ 
    for (int i = 0; i< possibleOptions.length -1;i++) 
    { 
     if (possibleOptions[i] != null) 
     System.out.println(i + " " + possibleOptions[i]); 
    } 
} // end of printOptions() method 

public String[] returnOptions() 
{ 
    return possibleOptions; 
} 

public void selectedOptionSetUp(int userOptionSelected) 
{ 
    System.out.println(""); 
    String textOfOption = possibleOptions[userOptionSelected]; 

    if (isItemInArray(newAreaOptions,textOfOption)) 
    { 
     checkGainItem("Leave",textOfOption); 



     if(areaReqItem){ 
      if (userHasItem(neededItem)){ 
       sectorID = 0; 
       setAreaID(textOfOption); 
       setAreaDescription(); 
       printArea(); 
      } 
      else System.out.println("You do not have an item needed to continue\n"); 
     } 
     else{ 
      sectorID = 0; 
      setAreaID(textOfOption); 
      setAreaDescription(); 
      printArea(); 
     } 
     if(gainedItemText != null){ 
      System.out.println(gainedItemText); 
     } 

    } 
    else if(isItemInArray(descriptorOptions,textOfOption)) 
    { 
     checkGainItem("Option",textOfOption); 

     if(descriptorReqItem){ 
      if(userHasItem(neededItem)){ 
       printDescriptorOption(textOfOption); 
      } 
      else System.out.println("You do not have an item needed to continue\t"); 
     } 
     else printDescriptorOption(textOfOption); 

     if(gainedItemText != null){ 
      System.out.println(gainedItemText); 
     } 
    } 
    else 
    { 
     checkGainItem("Exit",textOfOption); 



     if(optionRequiredItem){ 
      if(userHasItem(neededItem)){ 
       setSector(textOfOption); 
      } 
      else System.out.println("You do not have an item needed to continue\t"); 
     } 
     else setSector(textOfOption); 
     if(gainedItemText != null){ 
      System.out.println(gainedItemText); 
     } 
    } 
    gainedItemText = null; 
    optionRequiredItem = false; 
    areaReqItem = false; 
    descriptorReqItem = false; 
    neededItem= null; 
    getSectorDescription(); 
    printSectorDescription(); 
    Arrays.fill(possibleOptions, null);; 
    Arrays.fill(newAreaOptions,null); 
    Arrays.fill(descriptorOptions, null); 
} 

private void setSector(String optionText) 
{ 
    try 
    { 
     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 

     allLoops: 

     if (findCorrectArea(gameFileXML)){ 
      while (findEventLoc(gameFileXML,XMLStreamConstants.END_ELEMENT,"Sectors") == false){ 
       if(findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,"Sector")){ 
        while(gameFileXML.hasNext()){ 
         if(findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,"Exit")){ 
          int tempSectorID = Integer.parseInt(returnAttData(gameFileXML,"ID")); 
          if(gameFileXML.getElementText().equals(optionText)){ 
           sectorID= tempSectorID; 
           gameFileXML.close(); 
           gameFile.close(); 
           break allLoops; 
          } 
          else gameFileXML.next();  
         } 
         else gameFileXML.next(); 
        } 
       }  
       else gameFileXML.next(); 
      } //end of first while 
     }    
     else gameFileXML.next(); 

     gameFile.close(); 
     gameFileXML.close(); 
     gameFile = null; 
     gameFileXML = null; 
    } 

    catch (IOException | XMLStreamException e) 
    { 
     System.out.println(e); 
    } 
} 

private void setAreaID(String exitText) 
{ 
    try 
    { 
     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 


      if(findCorrectSector(gameFileXML)) 
      { 
       boolean foundNewAreaID = false; 
       while(foundNewAreaID == false){ 
        if (findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,"Leave")){ 
         int tempAreaID = Integer.parseInt(returnAttData(gameFileXML,"ID")); // FLAG possible bug issue 
         if (gameFileXML.getElementText().equals(exitText)){ 
          areaID = tempAreaID; 
          foundNewAreaID = true; 
         } 
         else gameFileXML.next(); 
        } 
        else gameFileXML.next(); 
       } 
      } 
      else gameFileXML.next(); //possibly dangerous to have this with a while inside if? 

     gameFile.close(); 
     gameFileXML.close(); 
     gameFile = null; 
     gameFileXML = null; 
    } 

    catch (IOException | XMLStreamException e) 
    { 
     System.out.println(e); 
    } 
} // end of setArea() method 

private void setAreaDescription() 
{ 
    try 
    { 
     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 

     allLoops: 
     while(gameFileXML.hasNext()) 
     { 
      if(gameFileXML.getEventType() == XMLStreamConstants.START_ELEMENT && gameFileXML.getLocalName().equals("Area")) 
      { 
       if(Integer.parseInt(returnAttData(gameFileXML,"ID")) == areaID) 
       { 
        while ((gameFileXML.getEventType() == XMLStreamConstants.END_ELEMENT && gameFileXML.getLocalName().equals("Description"))== false) 
        { 
         if (gameFileXML.getEventType() == XMLStreamConstants.START_ELEMENT && gameFileXML.getLocalName().equals("Description")) 
         { 
          areaDescription = gameFileXML.getElementText(); 
          break allLoops; 
         } 
         else gameFileXML.next(); 
        } 
       } 
       else gameFileXML.next(); 
      } 
      else gameFileXML.next(); 
     } 
     gameFileXML.close(); 
     gameFile.close(); 
     gameFileXML = null; 
     gameFile = null; 
    } 

    catch (IOException | XMLStreamException e) 
    { 
     System.out.println(e); 
    } 
} 

private void printDescriptorOption(String userOption) 
{ 
    try 
    { 
     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 
     allLoops: 
     while(gameFileXML.hasNext()) 
     { 
      if(gameFileXML.getEventType() == XMLStreamConstants.START_ELEMENT && 
        gameFileXML.getLocalName().equals("Area") && 
        Integer.parseInt(returnAttData(gameFileXML,"ID")) == areaID) 
      { 
       while((gameFileXML.getEventType() == XMLStreamConstants.END_ELEMENT && gameFileXML.getLocalName().equals("Area"))== false) 
       { 
        if(gameFileXML.getEventType() == XMLStreamConstants.START_ELEMENT && 
          gameFileXML.getLocalName().equals("Sector") && 
          Integer.parseInt(returnAttData(gameFileXML,"ID")) == sectorID) 
        { 
         while((gameFileXML.getEventType() == XMLStreamConstants.END_ELEMENT && 
           gameFileXML.getLocalName().equals("Sector")) == false) 
         { 
          if(gameFileXML.getEventType() == XMLStreamConstants.START_ELEMENT && 
            gameFileXML.getLocalName().equals("Option")) 
          { 
           String tempOptionString = gameFileXML.getAttributeValue(0); 
           if(gameFileXML.getElementText().equals(userOption)) 
           { 
            System.out.println(tempOptionString + "\n"); 
            gameFileXML.close(); 
            gameFile.close(); 
            break allLoops; 
           } 
           else gameFileXML.next(); 
          } 
          else gameFileXML.next(); 
         } 
        } 
        else gameFileXML.next();  
       } 
      } 
      else gameFileXML.next(); 
     } 
     gameFile.close(); 
     gameFileXML.close(); 
     gameFile = null; 
     gameFileXML = null; 
    } 
    catch (IOException | XMLStreamException e){ 
     System.out.println(e); 
    } 
} 

private void printArea(){ 
     if(testAreaID != areaID){ 
      System.out.println(areaDescription); 
     } 
    } // end of printArea() method 

private void checkGainItem(String optionType, String optionText){ 
    String gainedItem = null; 
    try{ 

     FileReader gameFile = new FileReader(gameFileName); 
     XMLStreamReader gameFileXML = inputFactory.createXMLStreamReader(gameFile); 

     if (findCorrectSector(gameFileXML)){ 
      while(gameFileXML.hasNext()){ 
       if(findEventLoc(gameFileXML,XMLStreamConstants.START_ELEMENT,optionType)){ 
        String potentialItem = returnAttData(gameFileXML,"GainItem"); 
        String potentialItemResponse = returnAttData(gameFileXML,"GainItemText"); 
        if(gameFileXML.getElementText().equals(optionText)){ 
         gainedItem = potentialItem; 
         gainedItemText = potentialItemResponse; 
         break; 
        }  
       } 
       else gameFileXML.next(); 
      } 
     } 
     else gameFileXML.next(); 
     gameFile.close(); 
     gameFileXML.close();  

     if(gainedItem != null){ 
      if(isItemInArray(userGainedItems,gainedItem)){ 
       gainedItemText="an item was here"; 
      } 
      else { 
       addToArray(userGainedItems,gainedItem); 
      } 
     } 
     gameFileXML.close(); 
     gameFile.close(); 
     gameFileXML = null; 
     gameFile = null; 
    } 
    catch (IOException | XMLStreamException e){ 
     System.out.println(e); 
    } 
} 

private String returnAttData(XMLStreamReader reader, String att){ 
    int count = reader.getAttributeCount(); 
    String attVal = null; 
    for(int i = 0; i < count; i++){ 
     if(reader.getAttributeLocalName(i).equals(att)){ 
      attVal = reader.getAttributeValue(i);//this should ALWAYS happen, or code might break 
      break; 
     } 
    } 
    return attVal; 
} 

private boolean findEventLoc(XMLStreamReader reader, int ele, String eleName){ 
    boolean foundEvent = false; 

    if(reader.getEventType() == ele && reader.getLocalName().equals(eleName)){ 
     foundEvent= true;; 
    } 
    else foundEvent = false; 
    return foundEvent; 
} 

private boolean findIntro(XMLStreamReader reader) throws XMLStreamException{ 
    boolean foundIntro = false; 

    while(foundIntro == false){ 
     if(findEventLoc(reader,XMLStreamConstants.START_ELEMENT,"Intro")){ 
      foundIntro = true; 
     } 
     else reader.next(); 
    } 
    return foundIntro; 
} 
private boolean findCorrectArea(XMLStreamReader reader) throws XMLStreamException{ 
    boolean foundCorrectArea = false; 
    //assumes foundCorrectArea will always become true 
    while(foundCorrectArea == false) { 
    if(findEventLoc(reader,XMLStreamConstants.START_ELEMENT,"Area")){ 
     if (Integer.parseInt(returnAttData(reader,"ID")) == areaID) { 
      foundCorrectArea = true; 
     } 
     else reader.next(); 
    } 
    else reader.next(); 
    } 
    return foundCorrectArea; 
} 

private boolean findCorrectSector(XMLStreamReader reader) throws XMLStreamException{ 
    boolean foundCorrectSector = false; 

    while (foundCorrectSector == false){ 
     if(findCorrectArea(reader)){ 
      while(foundCorrectSector == false) { 
       if(findEventLoc(reader,XMLStreamConstants.START_ELEMENT,"Sector")){ 
        if(Integer.parseInt(returnAttData(reader,"ID"))== sectorID){ 
         foundCorrectSector = true; 
        } 
        else reader.next(); 
       } 
       else reader.next(); 
      } 
     } 
     else reader.next(); 
    } 
    return foundCorrectSector; 
} 

private boolean userHasItem(String item){ 
    boolean hasItem = false; 
    if (isItemInArray(userGainedItems,item)){ 
     hasItem = true; 
    } 
    else hasItem = false; 
    return hasItem; 
} 

private void addToArray(String[] array, String item){ 
    for(int i = 0; i < array.length - 1;i++){ 
     if (array[i] == null){ 
      array[i]= item; 
      break; 
     } 
    } 
} 

private boolean isItemInArray(String[] array, String item){ 
    boolean itemFound = false; 
    for(int i=0; i < array.length -1;i++){ 
     if(array[i] == null) break; 
     if (array[i].equals(item)){ 
      itemFound = true; 
      break; 
     } 
    } 
    return itemFound; 
} 
} 

至於是什麼,我想知道一個概括:這將是一些更好的方式做同樣的事情,沒有STAX使用任何額外的自制類(如果那是什麼我正在使用,儘管只是冰山的一角)。可能有某處泄漏嗎? FileReader和XMLStreamReader使用null值是否合適?

謝謝你的時間。

回答

1

如果XML文件不是很大,我會推薦使用DOM解析器並應用XPath表達式。與STaX等流式XML代碼相比,此代碼編寫和維護起來要容易得多。我自己使用STaX處理大型文檔。

對於XPath,我通常使用http://jaxen.org/faq.html,而不是javax.xml.xpath代碼庫。

如果你的代碼中有內存使用問題,你應該試試像https://visualvm.github.io/這樣的分析工具或JProfiler這樣的分析器。

我會推薦在FileReaders上使用InputStreams。 FileReader類對XML文件的字符編碼進行了假設。

+0

你能提供一個鏈接或解釋你自己關於FileReader類的假設嗎?此外,我特意要求更好的方法來使用STaX來嘗試我的代碼,但是我確實認爲使用DOM等編寫和維護會更容易,事實上,在此程序的備用寫入中,我正在使用JDOM,我只是爲了更好地理解STaX,我想在這裏專門使用STaX。如果可以的話,請解釋一下分析工具和分析器的不同之處,或者將我的一些泛型關聯起來而不是特定的實例?感謝您的答覆。 –

+0

https://docs.oracle.com/javase/7/docs/api/java/io/FileReader.html - 如果直接使用輸入流,則XML解析器將從XML聲明中推斷出字符編碼,例如< ?xml version =「1.0」encoding =「utf-8」?>。 –

+0

我不確定我看到問題,應該字符編碼不是作爲XML聲明狀態?另外,看到FileReader擴展了InputStreams,你仍然可以使用getEncoding方法,我們說的是你指的是什麼,或者我錯過了什麼? –