いくつかの選択肢があります:
1ファイルを読み込んで処理してから書き戻します(そのファイルをロックする必要があります)。
2バイナリファイルを使用し、テキスト処理(行ロック付き)を最適化するために、リンクリストなどの特殊なデータ構造を作成(使用)します。
3-準備完了データベースを使用してください。
が 、4-、ファイル内で使用仮想ファイルシステムを、1つのファイルのように各行を扱い、以下を参照してください。https://github.com/lotrfan/vfsとhttps://github.com/blang/vfs(データベースサーバなど)のファイルマネージャを使用して
は、ファイルロックのジレンマを解決します。
ファイルを使用する目的が、送信者プログラムが新しい行と受信者プログラムを追加する単方向通信であれば、os pipes(名前付きパイプ(FIFO))またはその他のinteropメソッドを使用する方が良いです。
Linux用参照:Windows用Unix FIFO in go?
:
サンプルファイルライター:
package main
import (
"bufio"
"fmt"
"os"
"time"
)
func main() {
f, err := os.OpenFile("/tmp/file.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
defer f.Close()
for i := 0; ; i++ {
w := bufio.NewWriter(f)
_, err := fmt.Fprintln(w, i)
if err != nil {
panic(err)
}
w.Flush() // Flush writes any buffered data to the underlying io.Writer.
f.Sync() // commit the current contents of the file to stable storage.
fmt.Println("write", i)
time.Sleep(500 * time.Millisecond)
}
}
サンプルファイルリーダー:
package main
import (
"fmt"
"os"
"time"
)
func main() {
f, err := os.OpenFile("/tmp/file.txt", os.O_RDWR, 0666)
if err != nil {
panic(err)
}
defer f.Close()
i := 0
for {
n, err := fmt.Fscanln(f, &i)
if n == 1 {
fmt.Println(i)
}
if err != nil {
fmt.Println(err)
return
}
time.Sleep(500 * time.Millisecond)
}
}
ファイル全体を書き換えずに、ファイルの先頭から行を削除することはできません。あなたのsedの例は、同じことをしている間に追加された行を失うことと同じ問題を抱えています。前回の最後の行を処理している間に書かれた行だけが失われているため、競合は小さくなります –
失敗から保護するために行を削除する目的はありますか?その場合、最新の行が処理された状態ファイルを作成し、起動時にそれを確認し、その場所から処理を開始する方がよい場合があります。 EOFを押すと、ファイルを安全に削除できることがわかります。 – jxstanford
各行をループし、処理された行を文字列変数に連結してから、(一度ループが終了すると)文字列変数のファイル使用内容を書き直すことができます。 – openwonk