2016-08-04 133 views
6

我必須從我的Java應用程序讀取文本文件。Java中的併發讀/寫文件

該文件包含許多行,並且此文件每隔X分鐘從外部未知應用程序更新,該應用程序會將新行添加到該文件。

我必須讀取文件中的所有行,然後刪除剛剛讀取的所有記錄。

是否可以讓我逐行讀取文件,刪除我讀的每一行,同時允許外部應用程序將其他行附加到文件中?

此文件位於Samba共享文件夾中,因此我使用jCIFS來讀取/寫入文件和BufferedReader Java類。

在此先感謝

+0

更改由不在您控制下的應用程序寫入的文件是一個壞主意。你爲什麼需要刪除?也許只是爲了保持目前已讀多少行的標記而不更改文件就足夠了? – RealSkeptic

+0

這就是'Socket Writing'和'RESTful POST'命令的作用。 –

+0

@RealSkeptic我需要刪除或更新我剛剛閱讀的行,因爲我認爲這是將行標記爲「已處理」的最簡單方法。處理完一行後,我必須存儲在一個MySQL表中,因此我不需要將行留在文件中。 –

回答

1

問題是我們不知道如何在外部應用程序的寫入和/或重新使用這個文件。如果在外部應用程序使用計數器正確運行時刪除行,可能會出現問題...

除非您知道其他應用程序的工作方式,否則沒有好的解決方案。

2

我不知道完美的解決你的問題,但我會不同的解決這個問題:

  • 重命名文件(帶有時間戳給它一個唯一的名稱)
  • 的Appender的工作將隨後自動重新創建
  • 過程中的時間標記的文件(無需刪除他們,讓他們在的地方,以便以後可以看看發生了什麼)
+0

「appender作業會自動重新創建它」 - >不確定,例如,如果它只在啓動時執行。 – N0un

+0

@ N0un不確定,不錯,但值得一試。 –

+0

@SeanPatrickFloyd除非客戶期望他們的應用程序在生產環境中以非常特定的方式執行此操作。 –

0

是否可以讓我逐行讀取文件,刪除讀取的每一行,並同時允許外部應用程序將其他行附加到文件中?

是的,你可以打開同一個文件來讀寫多個進程。例如,在Linux中,您將爲同一個文件獲得兩個單獨的file descriptors。對於大小爲PIPE_BUF, or 4096 bytes in Linux,的文件寫入,假設這些操作是原子操作是安全的,這意味着內核正在處理鎖定和解鎖以防止競爭條件。

假設進程A正在寫入文件已將其打開爲APPEND,則每次進程A告知內核爲write()時,它將首先尋找文件的大小(文件末尾)。這意味着只要在進程A的寫操作之間完成,就可以安全地從進程B刪除文件中的數據。只要進程A的寫操作不超過PIPE_BUF,Linux就會保證它們是原子的,即流程A可以垃圾寫入操作,流程B可以不斷刪除/寫入數據,並且不會導致任何時髦的行爲。

Java爲您提供了implemented File Locks。但重要的是要明白,它只是「諮詢」,而不是「強制性的」。 Java不強制限制,這兩個進程都必須執行檢查以查看是否有另一個進程持有該鎖。

+0

鎖定? Linux會處理它?你能否顯示確認這個斷言的文件? – RealSkeptic

+0

@RealSkeptic我無法從Linus Torvald找到官方帖子。但是,如果你谷歌它,你會發現在書籍,網站和操作系統課程豐富的證據。 [這是一個例子](http://www.cim.mcgill.ca/~franco/OpSys-304-427/lecture-notes/node27.html)。此外,更多[stackoverflow支持](http://stackoverflow.com/a/2751750/1241782)。 –

+0

*對於大小爲PIPE_BUF的文件寫入,或在Linux中4096字節的文件寫入,可以安全地假設操作是原子操作,這意味着內核正在處理鎖定和解鎖以防止競爭條件。*通常是真的 - 但在這種情況下一個共享文件系統,顯然是跨網絡連接更新的。從正在寫入的文件中讀取很難用本地文件上的低級別C代碼可靠地執行 - 通過網絡在Java中進行*和*在寫入過程中同時修改文件將極其困難。 –