簡體   English   中英

迭代文本文件時嵌套while循環的奇怪行為

[英]Strange behavior of Nested while loop while iterating over a text file

我是Java新手。 我試圖遍歷幾個.txt文件,以將文件的一行與第二個文件的每一行進行比較。 這是我的兩個文件: listread.txtcsvread.txt

這是我正在使用的代碼:

try {
        BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
        BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
        String csvItem, listItem;
        int count =0;
        while((csvItem = csvReader.readLine()) != null){
            System.out.println("before second loop:"+csvItem);
            while ((listItem = listReader.readLine())!= null) {
                System.out.println("list Item: "+listItem.toLowerCase().split("¬")[1]);
                System.out.println("csv Item: "+csvItem.toLowerCase());
                if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
                        count++;
                }
             }
        }

    }catch(Exception e){
            e.printStackTrace();
    }

當我運行此命令時,僅將csvread.txt的第一行(存儲在變量csvItem )與csvItem的所有行進行listread.txt 這是示例輸出:

before second loop:Record Category   
list item: provisions
csv Item: record category    
list item: request category
csv Item: record category    
list item: elevator
csv Item: record category    
list item: assessment
csv Item: record category    
list item: associates
csv Item: record category    
list item: score
csv Item: record category    
list item: attachments
csv Item: record category

它只有在所有行迭代list.txt文件與第一線csvread.txt文件。 不會繼續前進到csvread.txt的第二行,並且該程序結束在最后一行拋出錯誤:

java.lang.ArrayIndexOutOfBoundsException: 1
    at test.main(test.java:52)

引用行System.out.println("list item: "+listItem.toLowerCase().split("¬")[1]); 該語句與我猜想的迭代無關。 不知道為什么會引發此錯誤。

但是,當我注釋掉第二個for循環時,它可以對csvread.txt文件中的所有行進行很好的迭代。 這是一個示例輸出,其中僅第一個while循環和第二個循環被注釋掉了:

before second loop:Record Category   
before second loop:Type 
before second loop:Name
before second loop:State
before second loop:Number
before second loop:ID (Self)
before second loop:Parent
before second loop:Title

僅當存在嵌套循環時,才會發生此問題。 當只有一個循環時,根本沒有問題。 有人可以闡明這種奇怪的行為嗎? 另外我該如何克服呢?

編輯:我添加了一個if條件來檢查行是否包含¬因為我在該字符上分割了行:

 if(listItem.contains("¬")){
        System.out.println("list item: "+listItem.toLowerCase().split("¬")[1]);
        System.out.println("csv Item: "+csvItem.toLowerCase());
        if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
                count++;
         }
   }

不,我再也沒有例外。 但是,該行為仍然很奇怪。 這是添加if之后的輸出:

before second loop:Record Category   
    list item: provisions
    csv Item: record category    
    list item: request category
    csv Item: record category    
    list item: elevator
    csv Item: record category    
    list item: assessment
    csv Item: record category    
    list item: associates
    csv Item: record category    
    list item: score
    csv Item: record category    
    list item: attachments
    csv Item: record category
    before second loop:Type 
    before second loop:Name
    before second loop:State
    before second loop:Number
    before second loop:ID (Self)
    before second loop:Parent
    before second loop:Title

現在的其它元素被遍歷在csvread.txt但在線路中的比較listread.txt不除了第一元件hapeening。

任何幫助,將不勝感激。 謝謝!

使用嵌套循環時,內部循環將完全執行。 然后執行控制從內​​循環中出來,並開始外循環的下一次迭代。 因此,如果要逐行比較兩個文件的內容,則不應有任何內部循環。 下面是在這種情況下可以嘗試執行的示例代碼。 雖然,我還沒有測試。

try {
    BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
    BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
    String csvItem, listItem;
    int count =0;
    while((csvItem = csvReader.readLine()) != null){
        System.out.println("before second loop:"+csvItem);
        listItem = listReader.readLine();
        if (listItem != null){
            if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
                    count++;
            }
        }else{
            //The listItem has no more lines to compare, so ending the process.
            break;
        }
    }

}catch(Exception e){
        e.printStackTrace();
}

我希望這有幫助。

注意:給出上述答案的前提是,要求是逐行比較兩個文件的內容。

您的訪問權限

listItem.toLowerCase().split("¬")[1]

至關重要,因為您始終希望所有行都帶有您的“¬”。 如果不是這種情況,則拆分將不會返回數組,並且您將在位置[1]處訪問returend數組,該數組將失敗並返回IndexOutOfBounds。

從我對listReader評論擴展到第一次迭代后指向文件的末尾。 BufferedReader不提供移動文件指針的機制,因此一種簡單的方法是將listReader的創建移動到外部循環內部:

try {
    BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"));
    // BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
    String csvItem, listItem;
    int count =0;
    while((csvItem = csvReader.readLine()) != null){
        System.out.println("before second loop:"+csvItem);
        BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
        while ((listItem = listReader.readLine())!= null) {
            System.out.println("list Item: "+listItem.toLowerCase().split("¬")[1]);
            System.out.println("csv Item: "+csvItem.toLowerCase());
            if(listItem.toLowerCase().split("¬")[1].contains(csvItem.toLowerCase())){
                    count++;
            }
         }
    }

}catch(Exception e){
        e.printStackTrace();
}

因此,每次迭代都會有一個新的listReader ,它從文件的頂部開始。

但這可能是太多的I / O。 如果list.txt的大小不是太大,則可能只讀取一次,解析它,然后存儲在Set<String>以便以后進行比較:

    try (BufferedReader listReader = new BufferedReader(new FileReader("/data/list.txt"));
            BufferedReader csvReader = new BufferedReader(new FileReader("/data/csvread.txt"))) {
        String listItem = null;
        Set<String> listItems = new HashSet<>();
        while ((listItem = listReader.readLine()) != null) {
            listItems.add(listItem.toLowerCase().split("¬")[1]);
        }

        String csvItem;
        int count = 0;
        while ((csvItem = csvReader.readLine()) != null) {
            System.out.println("before second loop:" + csvItem);

            for (String item : listItems) {
                System.out.println("list Item: " + item);
                System.out.println("csv Item: " + csvItem.toLowerCase());
                if (item.contains(csvItem.toLowerCase())) {
                    count++;
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

還移至try-with-resources,以確保正確關閉csvReaderlistReader

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM