Golangでのシステムのディスク容量の取得

29065 ワード

ディスク使用量の取得(Linux/Macで有効)

import (
    "syscall"
)

type DiskStatus struct {
    All  uint64 `json:"all"`
    Used uint64 `json:"used"`
    Free uint64 `json:"free"`
}

// disk usage of path/disk
func DiskUsage(path string) (disk DiskStatus) {
    fs := syscall.Statfs_t{}
    err := syscall.Statfs(path, &fs)
    if err != nil {
        return
    }
    disk.All = fs.Blocks * uint64(fs.Bsize)
    disk.Free = fs.Bfree * uint64(fs.Bsize)
    disk.Used = disk.All - disk.Free
    return
}

メモリ使用量の取得

import (
    "runtime"
)

type MemStatus struct {
    All  uint32 `json:"all"`
    Used uint32 `json:"used"`
    Free uint32 `json:"free"`
    Self uint64 `json:"self"`
}

func MemStat() MemStatus {
    //    
    memStat := new(runtime.MemStats)
    runtime.ReadMemStats(memStat)
    mem := MemStatus{}
    mem.Self = memStat.Alloc

    //    , linux/mac   
    //system memory usage
    sysInfo := new(syscall.Sysinfo_t)
    err := syscall.Sysinfo(sysInfo)
    if err == nil {
        mem.All = sysInfo.Totalram * uint32(syscall.Getpagesize())
        mem.Free = sysInfo.Freeram * uint32(syscall.Getpagesize())
        mem.Used = mem.All - mem.Free
    }
    return mem
}

後記


Windowsでのサポートが最も弱いのは明らかですが、もちろん、win 32 APIを呼び出すことで欠落した情報を取得することもできます.
GolangのAPIは、上述syscallのように完全にプラットフォームにまたがるものではない.Statfs_t構造体は、Windows下にはない

2013年4月6日更新、windowsでディスクスペースを取得する方法


win 32 apiを呼び出す
func main() {
    kernel32, err := syscall.LoadLibrary("Kernel32.dll")
    if err != nil {
        log.Panic(err)
    }
    defer syscall.FreeLibrary(kernel32)
    GetDiskFreeSpaceEx, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GetDiskFreeSpaceExW")

    if err != nil {
        log.Panic(err)
    }

    lpFreeBytesAvailable := int64(0)
    lpTotalNumberOfBytes := int64(0)
    lpTotalNumberOfFreeBytes := int64(0)
    r, a, b := syscall.Syscall6(uintptr(GetDiskFreeSpaceEx), 4,
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("C:"))),
        uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
        uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
        uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)), 0, 0)

    log.Printf("Available  %dmb", lpFreeBytesAvailable/1024/1024.0)
    log.Printf("Total      %dmb", lpTotalNumberOfBytes/1024/1024.0)
    log.Printf("Free       %dmb", lpTotalNumberOfFreeBytes/1024/1024.0)
}

またはより単純なバージョン
func main() {
    h := syscall.MustLoadDLL("kernel32.dll")
    c := h.MustFindProc("GetDiskFreeSpaceExW")
    lpFreeBytesAvailable := int64(0)
    lpTotalNumberOfBytes := int64(0)
    lpTotalNumberOfFreeBytes := int64(0)
    r2, _, err := c.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("F:"))),
        uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
        uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
        uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
}