2013-03-04 49 views
3

每隔5秒(例如),服務器會檢查文件是否已添加到特定目錄。如果是,它會讀取並處理它們。有關文件可能相當大(例如100多莫),因此將它們複製/上傳到上述目錄可能會很長。讀取尚未完成複製/上傳的文件內容

如果服務器試圖訪問尚未完成複製/上傳的文件,該怎麼辦? JAVA如何管理這些併發訪問?它依賴於服務器的操作系統嗎?


我作了嘗試,複製從遠程服務器〜1300000線TXT文件(即約200 Mo)的我的本地計算機:它需要大約5秒。在這個失誤,我運行下面的Java類:

public static void main(String[] args) throws Exception { 

    String local = "C:\\large.txt"; 

    BufferedReader reader = new BufferedReader(new FileReader(local)); 
    int lines = 0; 
    while (reader.readLine() != null) 
     lines++; 
    reader.close(); 

    System.out.println(lines + " lines"); 

} 

我得到以下異常:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at java.util.Arrays.copyOf(Arrays.java:2882) 
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100) 
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:515) 
    at java.lang.StringBuffer.append(StringBuffer.java:306) 
    at java.io.BufferedReader.readLine(BufferedReader.java:345) 
    at java.io.BufferedReader.readLine(BufferedReader.java:362) 
    at main.Main.main(Main.java:15) 

當運行類,一旦文件完成被複制,我得到的預期輸出(即1229761 lines),所以這個例外不是由於文件的大小(正如我們首先想到的那樣)。 JAVA在後臺做什麼,拋出了這個異常呢?

+0

您是否嘗試過使用大量的Xmx來確保它不是真正的OOME? – assylias 2013-03-04 11:34:26

+0

我的猜測是,readLine()在某種程度上實際上沒有找到換行符(可能是因爲換行符由於某種原因,不同的O.S.或某種編碼問題而不同),並且一次讀取非常大的行。 – ddmps 2013-03-04 11:40:05

+0

@assylias我試着用最大1 Gb的JAVA堆大小(即'-Xmx1024m')嘗試,但仍然拋出異常。 – sp00m 2013-03-04 13:18:24

回答

1

JAVA如何管理這些併發訪問?它依賴於服務器的操作系統嗎?

這取決於特定的操作系統。如果您在單個JVM中運行副本和服務器,則可能會有很大的幫助。但是,如果客戶端和服務器由不同的JVM代表(甚至更多,在不同的機器上啓動),它們都變成了特定平臺。

JavaDoc for AsynchronousFileChannel:

與FileChannel,通過這個類的一個實例提供的文件的視圖被保證是與由其他實例在同一程序中提供的相同文件的其他觀點的。然而,由這個類的實例提供的視圖可能與可能與其他併發運行程序看到的視圖一致,這是由於底層操作系統執行緩存以及網絡文件系統協議引起的延遲。無論編寫這些其他程序的語言如何,以及它們是在同一臺機器上還是在其他某臺機器上運行,情況都是如此。任何此類不一致的確切性質都與系統有關,因此未予指明。

1

爲什麼使用緩衝讀取器來計算行數?

來自javadoc: 從字符輸入流中讀取文本,緩衝字符以提供字符,數組和行的有效讀取。

這意味着它會「緩衝」,即。保存整個文件在內存中導致堆棧轉儲。嘗試一個FileReader。

+0

這個問題不是關於讀取行,而是訪問這樣的文件。我舉了一個例子來說明我的問題。 – sp00m 2013-03-04 20:58:12

+1

我的答案實際上仍然正確。你想知道爲什麼你要得到一個OOME,這是因爲你正在試圖把一個巨大的文件放在內存中。這給你兩個選擇:1.不要把它放在內存中(正如我上面所建議的那樣),或者2.按照其他人的建議,通過-Xmx標誌增加內存量。 – JoeG 2013-03-06 12:23:29