2015-09-07 29 views
-2

我在寫一段從.txt文件中讀取數據並將其存儲在二維數組中的Java代碼。對於某些文件,代碼工作得很好,但對於其他文件,它會拋出ArrayIndexOutOfBoundsException,儘管據我所知,該數組有足夠的空間!雖然有足夠的空間可用,但數組索引超出範圍

下面的代碼:

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 

public class ExtractData { 
    static String[][] data; 
    static String line; 
    static int amountOfEntries; 
    static int amountOfSeparators; 

    public static String[][] getData(String filename) throws IOException { 
     BufferedReader in = new BufferedReader(new FileReader(filename)); 
     System.out.println("Fetching data for file " + filename); 
     amountOfEntries = Utilities.countLines(filename); 
     amountOfSeparators = (Utilities.countOccurencesOfCharacter(filename, ' ')/amountOfEntries) + 1; 

     String[] temp = new String[amountOfEntries]; // for extracted data, still needs to be separated 
     int alpha = 0; 
     while((line = in.readLine()) != null) { 
      temp[alpha] = line; 
      alpha++; 
     } 
     in.close(); 
     System.out.println("Done!"); 

     System.out.println("Parsing Data to Cache..."); 
     String[][] parsedData = new String[amountOfEntries][amountOfSeparators]; 

     String[] parts = new String[amountOfSeparators]; 
     for (int i = 0; i < amountOfEntries; i++) { 
      parts = (temp[i]).split(" "); 
      for (int k = 0; k < amountOfSeparators; k++) { 
       parsedData[i][k] = parts[k]; 
       Utilities.debugMethod(filename + "[" + i + "][" + k + "]", parsedData[i][k]); 
      } 
     } 
     System.out.println("Done!"); 
     return parsedData; 
    } 

    public static void fetchDataAndParsetoSQL(String filename) throws IOException { 
     System.out.println("Present working directory: " + System.getProperty("user.dir")); 
     data = getData(filename); 
     System.out.println("Creating SQL statements and writing to file..."); 
     String tablename = Utilities.sqltableName(filename); 
     toSQL.SQLOutput(data, tablename, filename); 
     System.out.println("Done!"); 
    } 
} 

我得到的異常就行

parsedData[i][k] = parts[k]; 

這是非常煩人,我似乎無法在別處找到了答案的問題,特別是因爲即使對文本文件不起作用,它仍然在拋出異常之前正確解析文件的前60行。

任何人都有一個想法可能會導致這種情況?

+0

請顯示確切的異常以及'i'和'k'的值。請注意,您提交的代碼甚至不會編譯,因爲''''不是有效的字符文字。 –

+0

不應該考慮循環條件考慮的部分[]長度? – dly

+0

異常告訴你數組的大小和正在使用的索引值。其中之一不是你所期望的。並且在這裏抱怨錯誤時,總是會引用* entire *和* exact *錯誤信息。 –

回答

0
parts = (temp[i]).split(" "); 

此行返回一個新陣列,然後將其存儲在變量parts。您最初創建的數組不再由parts引用。

這個由split()創建的新數組將包含與分隔符之間的元素一樣多的元素。不保證確切地具有amountOfSeparators元素或更多。你內環聲明必須是:

for(int k = 0; k < amountOfSeparators && k < parts.size(); k++) { 

(另外一張紙條上的風格:使用的運營商一致的空間,如k < amountOfSeparatorsk< amountOfSeparators,並使用更具描述性的迭代器比ik,因爲在這種情況下,他們確實有除了天真的迭代器之外,你有許多其他的含義 - 更好的名稱可以使它更容易遵循複雜的循環。)

+0

謝謝你修復它! –

2

你假設parts陣列總會有amountOfSeparators元素,但每次調用parts = (temp[i]).split(" ");分配給它一個新的陣列,並且其中一些電話可能返回比預期更短的陣列。

下面的代碼將確保該parts陣列具有所需長度:

parts = (temp[i]).split(" "); 
parts = Arrays.copyOf(parts, amountOfSeparators); 
+0

是的!這正是發生的情況,只是爲每次遞歸調用打印出部分長度。但是,當(temp [i])。split(「」);有f.i. 74條目和77部分,我如何設置剩餘的未使用的索引讓我們說空?我認爲這將自動... –

+0

@SpadeJohnsson你可以在每次迭代中創建一個新的'amountOfSeparators'元素數組,然後將它複製到'(temp [i])。split(「」)'array 。這樣未使用的索引將爲空。 – Eran

+0

@SpadeJohnsson或更好 - 'parts =(temp [i])。split(「」); parts = Arrays.copyOf(parts,amountOfSeparators);' – Eran