2013-07-15 35 views
1

我需要分析兩個大型數據文件之間的差異,每個大型數據文件應該具有相同的結構。每個文件大小爲幾GB,可能有三千萬行或文本數據。數據文件非常大,我不願意將每個數據加載到它自己的數組中,因爲按順序遍歷行可能更容易。每一行都具有結構:從兩個大文件逐行比較數據

topicIdx, recordIdx, other fields... 

topicIdx和recordIdx是連續的,從零開始,並在每次迭代遞增+1,所以很容易找到他們的文件。 (不需要搜索;只需按順序向前遞增)。

我需要做的是這樣的:

for each line in fileA 
    store line in String itemsA 
     get topicIdx and recordIdx 
      find line in fileB with same topicIdx and recordIdx 
       if exists 
        store this line in string itemsB 
         for each item in itemsA 
          compare value with same index in itemsB 
           if these two items are not virtually equal 
            //do something 
       else 
        //do something else 

我寫了的FileReader和BufferedReader下面的代碼,但似乎對於這些API不提供我所需要的功能。任何人都可以告訴我如何解決下面的代碼,以便它實現我的願望?

void checkData(){ 
    FileReader FileReaderA; 
    FileReader FileReaderB; 
    int topicIdx = 0; 
    int recordIdx = 0; 
    try { 
     int numLines = 0; 
     FileReaderA = new FileReader("B:\\mypath\\fileA.txt"); 
     FileReaderB = new FileReader("B:\\mypath\\fileB.txt"); 
     BufferedReader readerA = new BufferedReader(FileReaderA); 
     BufferedReader readerB = new BufferedReader(FileReaderB); 
     String lineA = null; 
     while ((lineA = readerA.readLine()) != null) { 
      if (lineA != null && !lineA.isEmpty()) { 
       List<String> itemsA = Arrays.asList(lineA.split("\\s*,\\s*")); 
       topicIdx = Integer.parseInt(itemsA.get(0)); 
       recordIdx = Integer.parseInt(itemsA.get(1)); 
       String lineB = null; 
       //lineB = readerB.readLine();//i know this syntax is wrong 
       setB = rows from FileReaderB where itemsB.get(0).equals(itemsA.get(0)); 
       for each lineB in setB{ 
        List<String> itemsB = Arrays.asList(lineB.split("\\s*,\\s*")); 
        for(int m = 0;m<itemsB.size();m++){} 
        for(int j=0;j<itemsA.size();j++){ 
        double myDblA = Double.parseDouble(itemsA.get(j)); 
        double myDblB = Double.parseDouble(itemsB.get(j)); 
        if(Math.abs(myDblA-myDblB)>0.0001){ 
         //do something 
        } 
       } 
      } 
     } 
     readerA.close(); 
    } catch (IOException e) {e.printStackTrace();} 
} 
+0

如果您正在比較數據,請逐行進行。如果您正在比較二進制文件或文件,請逐字節進行。我的直覺告訴我行結尾是我認爲你還不知道的事情。 –

+0

我會先用Java代碼替換僞代碼 –

+0

對於像這樣的操作,Java太慢了。你應該把它寫在彙編中。 :) – Jashaszun

回答

2

您需要通過搜索鍵(recordIdx和topicIdx)排序兩個文件,所以你可以做樣的合併操作的這樣,你就永遠只能在內存中有兩個記錄

open file 1 
open file 2 
read lineA from file1 
read lineB from file2 
while (there is lineA and lineB) 
    if (key lineB < key lineA) 
     read lineB from file 2 
     continue loop 
    if (key lineB > key lineA) 
     read lineA from file 1 
     continue 
    // at this point, you have lineA and lineB with matching keys 
    process your data 
    read lineB from file 2 

注意。

2

如果你真的需要Java中的這個,爲什麼不使用java-diff-utils?它實現了一個衆所周知的差異算法。

+0

+1試圖幫助。同我留給戴爾威爾遜的評論一樣。 – CodeMed

1

考慮https://code.google.com/p/java-diff-utils/。讓其他人做重要的事情。

+0

這些文件有細微差別,例如一個文件可能有20位小數位,而另一個文件可能有一位小數位。一個文件使用無窮大,而另一個文件則爲無窮大提供了一個非常大的數字。我知道如何解決java中的這些差異......我只是不知道如何將這麼多的數據放入ArrayList中,而不必先將它們分解爲多個文件。 – CodeMed

+0

嘗試提供幫助。 – CodeMed