如何在Golang中提取/proc/meminfo的内存与交换区信息?
解决Golang从/proc/meminfo提取指定内存值的问题
原代码问题分析
你当前的代码每次循环都会初始化var n int(默认值为0),当扫描到的行不匹配MemFree: %d kB格式时,n保持0并被打印,所以会出现大量零值行。只有匹配到目标行时,n才会被赋值为正确的内存值。
方案一:检查扫描匹配结果
利用fmt.Sscanf的返回值(成功匹配的参数数量),只有当匹配成功时才输出值:
package main import ( "bufio" "fmt" "os" ) func main() { f, e := os.Open("/proc/meminfo") if e != nil { panic(e) } defer f.Close() s := bufio.NewScanner(f) for s.Scan() { var n int // 检查是否成功匹配1个参数 if cnt, _ := fmt.Sscanf(s.Text(), "MemFree: %d kB", &n); cnt == 1 { fmt.Println(n) } } // 检查扫描过程中是否出错 if err := s.Err(); err != nil { panic(err) } }
方案二:批量提取目标字段(更优)
如果需要提取多个字段(MemTotal、MemFree、MemAvailable、SwapTotal、SwapFree),可以用一个map存储目标字段,遍历每行解析键值对,匹配到目标字段时存入map,最后统一输出:
package main import ( "bufio" "fmt" "os" "strings" ) func main() { // 定义需要提取的目标字段 targetFields := map[string]int{ "MemTotal": 0, "MemFree": 0, "MemAvailable": 0, "SwapTotal": 0, "SwapFree": 0, } f, e := os.Open("/proc/meminfo") if e != nil { panic(e) } defer f.Close() s := bufio.NewScanner(f) for s.Scan() { line := s.Text() var keyStr string var value int // 解析每行的键和数值(忽略后面的kB) if cnt, _ := fmt.Sscanf(line, "%s %d", &keyStr, &value); cnt == 2 { // 去掉键名后的冒号 key := strings.TrimSuffix(keyStr, ":") // 如果是目标字段,更新值 if _, exists := targetFields[key]; exists { targetFields[key] = value } } } if err := s.Err(); err != nil { panic(err) } // 输出结果 fmt.Println("内存信息:") for k, v := range targetFields { fmt.Printf("%s: %d kB\n", k, v) } }
说明
- 方案二可以一次性提取所有需要的字段,避免多次编写重复的匹配逻辑
- 通过
strings.TrimSuffix处理键名后的冒号,确保能正确匹配目标字段 - 增加了对
bufio.Scanner扫描错误的检查,提升代码健壮性
内容的提问来源于stack exchange,提问作者bnhf
相关产品推荐
相关产品推荐

