英文:
GoLang tailing UTF16LE windows log file
问题
我可以帮你将这两个 Golang 脚本合并起来以追踪一个 UTF16LEBOM 编码的活动日志。以下是你提供的代码的翻译:
// 编辑:几乎可以工作。看起来 utfutil 没有延迟关闭。
package main
import (
"bufio"
"fmt"
"io"
"time"
"github.com/TomOnTime/utfutil"
)
func main() {
logfilefile := "C:/Users/user/Documents/EVE/logs/Chatlogs/chat_20220709_022129_1006197774.txt"
file, err := utfutil.OpenFile(logfilefile, utfutil.WINDOWS)
if err != nil {
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n')
if err != nil {
if err == io.EOF {
// 如果没有这个 sleep,会占用 CPU
time.Sleep(500 * time.Millisecond)
continue
}
break
}
fmt.Printf(string(line))
}
}
这是一个结合了两个示例的代码。第一个示例是用于追踪文件的代码,你可以在这里找到:https://medium.com/@arunprabhu.1/tailing-a-file-in-golang-72944204f22b
第二个示例是用于读取文件并使其可读且没有额外字符的代码,你可以在这里找到:https://github.com/TomOnTime/utfutil/
你可以将这两个示例的代码合并起来,以便追踪一个 UTF16LEBOM 编码的活动日志,并在关键字 "die" 和 "prepare to die scumsucker!" 出现时进行标记。希望这可以帮到你!
英文:
How can I combine these two golang scripts to tail an active log that is UTF16LEBOM?
I am working on a log parser for a game (Eve Online). In the game chat logs can be saved, and I would like to use GoLang to read the running log and flag on keywords "die" in "prepare to die scumsucker!"
I've found two examples that work separately. Combining them is a challenge I've been unable to figure out. First tail equivalent here:
https://medium.com/@arunprabhu.1/tailing-a-file-in-golang-72944204f22b
Second reading the file so that is legible and doesn't have extra characters:
https://github.com/TomOnTime/utfutil/
I have been trying to replace the code from utfutil with the "equivalent" but it seems it is missing several functions.
// EDIT Almost working. It doesn't look like utfutil is defering the close.
package main
import (
"bufio"
"fmt"
"io"
"time"
"github.com/TomOnTime/utfutil"
)
func main() {
logfilefile := "C:/Users/user/Documents/EVE/logs/Chatlogs/chat_20220709_022129_1006197774.txt"
file, err := utfutil.OpenFile(logfilefile, utfutil.WINDOWS)
if err != nil {
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n')
if err != nil {
if err == io.EOF {
// without this sleep you would hogg the CPU
time.Sleep(500 * time.Millisecond)
continue
}
break
}
fmt.Printf(string(line))
}
}
<cut white space>
---------------------------------------------------------------
Channel ID: local
Channel Name: Local
Listener: Steve
Session started: 2022.07.07 16:18:21
---------------------------------------------------------------
[ 2022.07.07 17:11:44 ] Steve > hello world
[ 2022.07.07 17:11:48 ] John > hello world
[ 2022.07.07 17:11:51 ] James > hello world
[ 2022.07.07 19:36:53 ] Bob > hello world
答案1
得分: 1
你可以通过删除github.com/TomOnTime/utfutil
来简化你的代码(这只是对golang.org/x/text/encoding/unicode
的一个非常薄的封装)。此外,通常将任务链接起来比尝试一次性完成所有任务更简单;在这里,我从这个答案中借用了tailReader
(稍作修改)。
注意:我只是快速测试了下面的代码(并且手头没有一个“Eve Online”日志文件)。
package main
import (
"bufio"
"fmt"
"io"
"os"
"time"
"golang.org/x/text/encoding/unicode"
)
func main() {
file, err := newTailReader("./Local_20220707_170827_1006197774.txt")
if err != nil {
return
}
defer file.Close()
utf := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
reader := bufio.NewReader(utf.NewDecoder().Reader(file))
for {
line, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
break
}
fmt.Printf(string(line))
}
}
// 从 https://stackoverflow.com/a/31122253/11810946 复制的代码
// 并修改为在开始“tail”之前输出文件内容
type tailReader struct {
io.ReadCloser
}
func (t tailReader) Read(b []byte) (int, error) {
for {
n, err := t.ReadCloser.Read(b)
if n > 0 {
return n, nil
} else if err != io.EOF {
return n, err
}
time.Sleep(10 * time.Millisecond)
}
}
func newTailReader(fileName string) (tailReader, error) {
f, err := os.Open(fileName)
if err != nil {
return tailReader{}, err
}
return tailReader{f}, nil
}
英文:
You can simplify your code by removing github.com/TomOnTime/utfutil
(this is a very thin wrapper over golang.org/x/text/encoding/unicode
). It's also often simpler to chain tasks rather than trying to do everything at once; here I'm borrowing tailReader
(with a minor change) from this answer.
Note: I have only tested the below very quickly (and don't have an "Eve Online" logfile to hand).
package main
import (
"bufio"
"fmt"
"io"
"os"
"time"
"golang.org/x/text/encoding/unicode"
)
func main() {
file, err := newTailReader("./Local_20220707_170827_1006197774.txt")
if err != nil {
return
}
defer file.Close()
utf := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
reader := bufio.NewReader(utf.NewDecoder().Reader(file))
for {
line, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
break
}
fmt.Printf(string(line))
}
}
// Code copied from https://stackoverflow.com/a/31122253/11810946
// and modified to output contents of file before beginning to 'tail'
type tailReader struct {
io.ReadCloser
}
func (t tailReader) Read(b []byte) (int, error) {
for {
n, err := t.ReadCloser.Read(b)
if n > 0 {
return n, nil
} else if err != io.EOF {
return n, err
}
time.Sleep(10 * time.Millisecond)
}
}
func newTailReader(fileName string) (tailReader, error) {
f, err := os.Open(fileName)
if err != nil {
return tailReader{}, err
}
return tailReader{f}, nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论