2012-02-24 38 views
0

我有一個進程(實際上是一個web服務器),它將從客戶端進入的POST作爲日誌文件寫入日誌文件。BufferedReader readline在行完成之前

然後,我有一個單獨的進程,倒像是在一個循環(尾-f)日誌文件:

  BufferedReader reader = new BufferedReader(new FileReader(logFilePath)); 
      String line = null; 

      while (true) 
      { 
        if ((line = reader.readLine()) != null) 
        { 
          if (firstLine == null) firstLine = line; 
          processLine(line); 
          continue; 
        } 

        try 
        { 
          Thread.sleep(sleepTime); 
          long ts = System.currentTimeMillis(); 
        } catch (InterruptedException e) { 
          Thread.currentThread().interrupt(); 
          break; 
        } 
      } 

這工作的時間非常好99%,但偶爾,行我通過閱讀BufferedReader.readLine不是一個完整的行。我想這是因爲作家(網絡服務器)尚未完成將該行的所有字節清除到文件。

任何修復或解決此問題的建議?非常感謝!

+0

你有一種模式來檢測線路不完整? – VirtualTroll 2012-02-24 19:16:36

+0

只需一個快速指針:你不需要使用'while(true)... break',你可以使用一個變量來檢查是否應該繼續。 – Viruzzo 2012-02-24 19:18:02

+0

我認爲這可能會對您有所幫助: http://docs.oracle.com/javase/1.4.2/docs/api/java/io/FileDescriptor.html#sync() – nullpotent 2012-02-24 19:19:16

回答

1

在與多個需要同時訪問一個文件的多個進程一起工作(通常是一個進程一個接一個地進行)之後,我發現(與其他開發人員一起),一個「預告」文件很好地用於指示何時完成一個進程與需要被另一個進程訪問的文件進行交互。

我不知道你的web服務器多久寫一次這個日誌,也不知道你的Java進程需要多久才能讀取它,但是如果在每個進程訪問文件之間有時間流逝,一個預告文件可能是寫出來,表明當你的web服務器完成寫入文件。你的Java進程可以首先檢查尾部文件是否存在,然後找到它,刪除然後從日誌中讀取。

否則,您可能需要使用操作系統命令來確定您的網絡服務器是否正在寫入日誌,並且僅在日誌讀取器不在時才運行。 http://blog.bensmann.com/executing-operating-system-commands在Java中執行OS命令有一些很好的信息。

底線是需要建立某種固定的差距,以便這些過程不會同時讀取/寫入日誌。

+0

謝謝扎克。網絡服務器每秒寫入速度非常快,幾行代碼和數據庫數量都在增長。不知道檢查網絡服務器是否完成寫入會花費很多。 我實際上並不介意讀者稍微落後於作家,如果有幫助但不知道如何去做。 – 2012-02-24 22:54:51

-1

我最近面臨同樣的問題,讓我解釋一下bufferreader何時會用readline() 方法讀取不完整的行。它會在回車前遇到EOF時執行此操作。

中的BufferedReader readine的代碼是這樣的

if (nextChar >= nChars) 
        fill(); 
       if (nextChar >= nChars) { /* EOF */ 
        if (s != null && s.length() > 0) 
         return s.toString(); 

        else 
         return null; 
       } 

這表示,如果前車遇到EOF返回它會返回不管它已經閱讀。 但是,當我們調用readLine()並且在回車之前遇到EOF字符時,應該返回正確的代碼,它應該返回NULL而不是不完整的行。

我寫了我的擴展bufferedreader類,其中ReadLine在上面解釋的場景中返回NULL。

+1

什麼是「EOF字符」? – 2016-06-06 17:17:47

+0

您引用的代碼中沒有關於EOF字符的內容。沒有EOF字符。有一個EOF *條件。* – EJP 2016-06-06 18:50:29

相關問題