2014-07-01 62 views
0

我正在寫一個函數來獲取一個文本文件並計算它將行輸出到一個字符串數組時的行數。這樣做我有幾個例外,我需要注意。類函數有幾個變量,它們應該在整個函數中有一個範圍,但是當我在異常中的函數中寫入值時,return語句找不到它。我已經移動了聲明,沒有任何幫助讀取隱藏在java異常處理中的變量

返回的值「h5Files」「可能沒有被初始化」因爲我不知道數組會有多長時間,所以我無法將它初始化爲一定的長度。我這樣做的代碼中,我需要一種方法來告訴return語句,我現在有一個值

下面是代碼

public String[] ReadScanlist(String fileIn){ 

    int i; 
    String directory ="c:\\data\\"; // "\" is an illegal character 
    System.out.println(directory); 
    int linereader = 0; 
    String h5Files[]; 
    File fileToRead = new File(directory + fileIn); 
    System.out.println(fileToRead); 


    try { 
     FileInputStream fin = new FileInputStream(fileToRead); // open this file 

     } 
    catch(FileNotFoundException exc) { 
     System.out.println("File Not Found"); 
     } 


    try{ 
     //read bytes until EOF is detected 
     do { 
      FileReader fr = new FileReader(fileToRead);// Need to convert to reader 
      LineNumberReader lineToRead = new LineNumberReader(fr); // Use line number reader class 


      // 
      while (lineToRead.readLine() != null){ 
       linereader++; 
       } 

      linereader = 0; 
      lineToRead.setLineNumber(0); //reset line number 
      h5Files = new String[linereader]; 
      while (lineToRead.readLine() != null){ 
       h5Files[linereader] = lineToRead.readLine(); // deposit string into array 
       linereader++; 
       } 
      return h5Files; 
      } 
     while(i !=-1); // When i = -1 the end of the file has been reached  
     } 
    catch(IOException exc) { 
     System.out.println("Error reading file."); 
     } 

    try{ 
     FileInputStream fin = new FileInputStream(fileToRead); 
     fin.close(); // close the file 
     } 
    catch(IOException exc) { 
     System.out.println("Error Closing File"); 
     } 
    return h5Files; 
    } 
+0

您可以使用的列出(例如ArrayList)的行而不是數組。你也重置你的h5Files數組0槽,所以會有一個IndexOutOfBoundException,我猜。 – peshkira

+0

你有什麼期望'返回'有一個'Exception'並且你的初始化代碼還沒有運行?在最好的情況下,這將是'null' ... –

+0

非常好的評論我會看看列表,我打算使用null作爲例外。謝謝,我將嘗試現在實施這些建議。 –

回答

0

你的代碼非常奇怪。例如這兩個塊是沒有意義的:

try { 
    FileInputStream fin = new FileInputStream(fileToRead); // open this file 

    } 
catch(FileNotFoundException exc) { 
    System.out.println("File Not Found"); 
    } 

try{ 
    FileInputStream fin = new FileInputStream(fileToRead); 
    fin.close(); // close the file 
    } 
catch(IOException exc) { 
    System.out.println("Error Closing File"); 
    } 

我不知道你在想什麼,他們這樣做,但除了第一個泄漏內存,他們什麼都不做。評論更令人擔憂,他們建議您需要在Java中更多地閱讀IO。

刪除這些塊和整理的碼的(運動聲明,格式化)給出了這樣的:

public String[] ReadScanlist(String fileIn) { 
    String directory = "c:\\data\\"; 
    String h5Files[]; 
    File fileToRead = new File(directory + fileIn); 
    try { 
     int i = 0; 
     do { 
      FileReader fr = new FileReader(fileToRead); 
      LineNumberReader lineToRead = new LineNumberReader(fr); 
      int linereader = 0; 
      while (lineToRead.readLine() != null) { 
       linereader++; 
      } 

      linereader = 0; 
      lineToRead.setLineNumber(0); 
      h5Files = new String[linereader]; 
      while (lineToRead.readLine() != null) { 
       h5Files[linereader] = lineToRead.readLine();      
       linereader++; 
      } 
      return h5Files; 
     } while (i != -1); 
    } catch (IOException exc) { 
     System.out.println("Error reading file."); 
    } 
    return h5Files; 
} 

我的論點的第一骨是File相關的代碼。首先,File摘要來自底層操作系統,所以使用/絕對沒問題。其次,還有一個原因是FileFile, String構造函數,此代碼應閱讀:

File directory = new File("c:/data"); 
File fileToRead = new File(directory, fileIn); 

但它確實應該使用新的API Path反正(見下文)。因此,您聲明h5Files[]。然後繼續閱讀整個文件來計算行數。然後將h5Files[]分配給正確大小的數組。最後你填寫數組。

如果您在分配h5Files[]之前在任何地方有錯誤您尚未初始化它,因此無法將其返回。這是編譯器告訴你的。

我不知道i在這段代碼中做了什麼,它在頂部被分配到0,然後從未重新分配。這是一個無限循環。

所以,你需要重新思考你的邏輯。如果您無法讀取文件,我會建議扔IOException從不return null - 這是一個反模式,並導致在您的代碼中檢查數千個null。如果你永遠不會return null你永遠不會檢查它。

我可以建議如下替代代碼:

如果你是在Java 7的:

public String[] ReadScanlist(String fileIn) throws IOException { 
    final Path root = Paths.get("C:/data"); 
    final List<String> lines = Files.readAllLines(root.resolve(fileIn), StandardCharsets.UTF_8); 
    return lines.toArray(new String[lines.size()]); 
} 

或者,如果你有Java的8:

public String[] ReadScanlist(String fileIn) throws IOException { 
    final Path root = Paths.get("C:/data"); 
    try (final Stream<String> lines = Files.lines(root.resolve(fileIn), StandardCharsets.UTF_8)) { 
     return lines.toArray(String[]::new); 
    } 
} 
+0

非常感謝! –

0

因爲我不知道過了多久陣列將是我無法初始化它 到一定的長度。

我不認爲一個數組是正確的解決方案然後 - 不要說它不能完成,但你會重新發明輪子。

我會建議你使用一個LinkedList代替,一樣的東西:

LinkedList<String> h5Files = new LinkedList<>(); 
h5Files.add(lineToRead.readLine()); 

另外,您可以通過該陣列設置成arbritary價值進行重新發明輪子,說10,然後重新大小它時,它得到充分,是這樣的:在一個安全的構造

h5Files = new String[10]; 
if (linereader = h5Files.size()) 
{ 
    String[] temp = h5Files; 
    h5Files = new String[2 * linereader]; 
    for (int i = 0; i < linereader; i++) 
    { 
    h5Files[i] = temp[i]; 
    } 

} 

無論這些解決方案將允許你初始化數組的一個(或陣列的替代),之前你的try塊,這樣你可以,如果訪問拋出任何例外

+0

'System.arraycopy'存在是有原因的。 –

0

這是你的問題。請使用我的評論來看看代碼的消解版本。

String h5Files[]; // here you define the variable. It still is not initialized. 
    try{ 
     .................. 
     do { 
      h5Files = new String[linereader]; // here you initialize the variable 
     } while(i !=-1); // When i = -1 the end of the file has been reached  
     .................. 
    catch(IOException exc) { 
     // if you are here the variable is still not initialized 
     System.out.println("Error reading file."); 
    } 

    // you continue reading file even if exception was thrown while opening the file 

我認爲現在問題更加清楚了。您嘗試打開文件和計數行。如果你成功,你創建數組。如果不是(即拋出異常),你會發現異常但仍然繼續讀取文件。但在這種情況下,您的數組未初始化。

現在該如何解決?

其實如果第一次讀取文件失敗,則無法繼續。例如,如果文件不存在,可能會發生這種情況。所以,當你拋出第一個異常或者根本不捕獲它時,你應該返回。事實上,如果在任何階段拋出異常,那麼與該文件無關。異常不是返回碼。這是存在例外的原因。

所以,只是不要捕捉異常。聲明您的方法爲throws IOException並刪除所有try/catch塊。