我正在编写一个文本文件爬虫程序并不断收到 ConcurrentModificationException。我知道这与使用 Iterator 有关,但我不确定如何修复它。请帮忙!
例外是:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(unknown Source)
at java.util.LinkedHashMap$KeyIterator.next(Unknown Source)
at TextCrawler.main(TextCrawler.java:112)
代码:
while(it1.hasNext() && wordCount2 < wordCountToFind2) { //while there are more files to be searched and the wordCount is less than max occurrences
wordCount2 = 0;
Iterator it3 = occurrencesVector.iterator();
while(it3.hasNext()) { //get current wordCount
wordCount = (Integer)it3.next();
wordCount2 += wordCount;
System.out.println("WordCount2...." + wordCount2); //Test
}
String nextFile = (String)it1.next(); //this is line 112
System.out.println("nextFile...." + nextFile + "\n" + "\n"); //Test
if(i > 0) { //skips the initial input filename (which is at the start of filenameSet) so it's not checked twice
System.out.println("Start searchFile method"); //Test
try{txtCr2.searchFile(nextFile, wordToFind2, wordCountToFind, caseSensitive);} //call searchFile method
catch(IOException e){System.out.println("txtCr2 exception, searchFile method didn't happen!"); e.printStackTrace();};
}
i++;
System.out.println("i = " + i);
}
searchFile 方法的完整代码:
public void searchFile(String filename, String wordTF, String wordCountTF, String caseS) throws IOException
{
FileReader aFileReader = new FileReader(new File(filename)); //make the file readable
BufferedReader aBufferedReader = new BufferedReader(aFileReader);
String newFile, lineFromFile, updatedLine = "", filePattern = "\\([a-zA-Z0-9]{1,32}.txt\\)", outputMessage = "";
char aChar;
int wordCount = 0, occurrencesToFind;
occurrencesToFind = Integer.parseInt(wordCountTF); //convert passed down String to int
filenameSet.add(new String(filename)); //add the filename to the LindedHashSet
while((lineFromFile = aBufferedReader.readLine()) != null) { //while lineFromFile is not empty
for(int i = 0; i < lineFromFile.length(); i++) {
aChar = lineFromFile.charAt(i); //go through each line character by character
if(Character.isLetterOrDigit(aChar) || Character.isWhitespace(aChar) || aChar == '(' || aChar == ')' || aChar == '.')
if(aChar == '(') //if the character is ( then add a space in front of it
updatedLine = updatedLine + " " + aChar;
else
if(aChar == ')') //if the character is ) then add a space after it
updatedLine = updatedLine + aChar + " ";
else
updatedLine = updatedLine + aChar; //if the character is a letter, digit or whitespace just add it to the updatedLine
} //all unwanted punctuation is removed
}
aFileReader.close();
aBufferedReader.close();
String [] fileArray = updatedLine.toLowerCase().split(" "); //split the updatedLine into an array at the whitespaces.
//for(int i = 0; i < fileArray.length; i++) //Test
//System.out.println(fileArray[i]);
boolean fileSearched = false;
while(wordCount < occurrencesToFind && !fileSearched) { //while the wordCount is less than the required wordCount and the file hasn't been completely searched.
if(caseS.equals("1")) { //if the word to be checked is case sensitive
for(int j = 0; j < fileArray.length; j++) { //for the length of the array
if(fileArray[j].equals(wordTF)) //if a word in the fileArray exactly equals the word to be searched
wordCount++; //add a count of one to the wordCount
if(fileArray[j].matches(filePattern)) { //if a word in the fileArray matches the filePattern e.g. (filename.txt)
newFile = fileArray[j].substring(1,fileArray[j].length() -1); //newFile is equal to the filePattern with round brackets removed.
System.out.println("New File found..." + newFile); //Test
filenameSet.add(new String(newFile)); //add it to the LinkedHashSet
}
}
fileSearched = true; //file has been searched
}
else { //else if the word to be checked isn't case sensitive
for(int j = 0; j < fileArray.length; j++) { //for the length of the array
if(fileArray[j].toLowerCase().equals(wordTF.toLowerCase())) //not case sensitive so make both search word and fileArray word lower case
wordCount++; //if they are equal add a count of one to the word count
if(fileArray[j].matches(filePattern)) { //if a word in the fileArray matches the filePattern e.g. (filename.txt)
newFile = fileArray[j].substring(1,fileArray[j].length() -1); //newFile is equal to the filePattern with round brackets removed.
System.out.println("New File found...." + newFile); //Test
filenameSet.add(newFile); //add it to the LinkedHashSet
}
}
fileSearched = true; //file has been searched
}
}
occurrencesVector.addElement(new Integer(wordCount)); //add the wordCount to the occurrences LinkedHashSet
System.out.println("occurrencesVector contains.." + occurrencesVector); //Test
System.out.println("filenameSet contains.." + filenameSet); //Test
System.out.println("End of searchFile method.\n\n"); //Test
}
发生向量:
public class TextCrawler
{
static LinkedHashSet<String> filenameSet = new LinkedHashSet<String>();
static Vector<Integer> occurrencesVector = new Vector<Integer>();
它1:
System.out.println("\nStarting initial file search in..." + startFile2);
try{txtCr.searchFile(startFile2, wordToFind2, wordCountToFind, caseSensitive);}
catch(IOException e){System.out.println("txtCr exception");};
boolean nextFileSearched = false;
int wordCount, wordCount2 = 0, wordCount3, wordCount4 = 0;
Iterator it1 = filenameSet.iterator();
Iterator it2 = occurrencesVector.iterator();
int i = 0;
while(it2.hasNext()) { //get current wordCount
wordCount = (Integer)it2.next();
wordCount2 += wordCount;
}
while(it1.hasNext() && wordCount2 < wordCountToFind2) { //while there are more files to be searched and the wordCount is less than max occurrences
wordCount2 = 0;