我需要从nfcapd二进制文件中获取有关源IP和目标IP的信息。问题在于文件大小。我知道用io或os包打开和读取非常大(超过1 GB)的文件是不可取的。
这是我的黑客攻击和选秀开始:
package main
import (
"fmt"
"time"
"os"
"github.com/tehmaze/netflow/netflow5"
"log"
"io"
"bytes"
)
type Message interface {}
func main() {
startTime := time.Now()
getFile := os.Args[1]
processFile(getFile)
endTime := time.Since(startTime)
log.Printf("Program executes in %s", endTime)
}
func processFile(fileName string) {
file, err := os.Open(fileName)
// Check if file is not empty. If it is, then exit from program
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Useful to close file after getting information about it
defer file.Close()
Read(file)
}
func Read(r io.Reader) (Message, error) {
data := [2]byte{}
if _, err := r.Read(data[:]); err != nil {
return nil, err
}
buffer := bytes.NewBuffer(data[:])
mr := io.MultiReader(buffer, r)
return netflow5.Read(mr)
}
我希望将文件拆分为24个流,然后在使用netflow package阅读后同时处理它。但我无法想象如何在分裂期间不丢失任何数据。
如果我错过了代码或说明中的内容,请修理我。我花了很多时间在网上搜索我的解决方案并考虑其他可能的实现。
任何帮助和/或建议都将受到高度赞赏。
文件具有以下属性(终端中的命令file -I <file_name>
):
file_name: application/octet-stream; charset=binary
命令nfdump -r <file_name>
之后的文件输出具有以下结构:
Date first seen Duration Proto Src IP Addr:Port Dst IP Addr:Port Packets Bytes Flows
每个属性都在自己的列上。
更新1: 不幸的是,由于二进制文件结构不同,通过nfcapd将文件保存到磁盘后,使用netflow包解析文件是impossible。这个答案由one个nfdump贡献者提供。
现在唯一的办法是在像pynfdump这样的go程序中从终端运行nfdump。
答案 0 :(得分:0)
IO在解析文件时几乎总是会成为限制因素,除非涉及大量计算,否则串行读取单个文件将是处理它的最快方法。
将文件换入bufio.Reader
并将其提交给Read
函数:
file, err := os.Open(fileName)
if err != nil {
log.Fatal((err)
}
defer file.Close()
packet, err := netflow5.Read(bufio.NewReader(file))
解析后,如果需要单独处理这些块,则可以拆分记录。