2017-10-04 45 views
2

編輯:@abhink指出,沒有調用Size()如何正確地獲取塊設備的尺寸?

我試了兩種不同的去法,然後再比較df。當然,所有3給出不同的結果:

package main 

import (
    "os" 
    "syscall" 
    "fmt" 
) 

func main() { 
    disk := "/dev/sda1" 
    statout, err := os.Stat(disk) 
    if err != nil { 
     fmt.Errorf("Error %x", err) 
     os.Exit(1) 
    } 
    println("os.Stat Size : ", statout.Size()) 

    var stat syscall.Statfs_t 
    syscall.Statfs(disk, &stat) 
    println("syscall.Statfs_t Type: ", stat.Type) 
    println("syscall.Statfs_t Bsize: ", stat.Bsize) 
    println("syscall.Statfs_t Blocks: ", stat.Blocks) 
} 

運行程序:

$ main 
os.Stat Size : 0 
syscall.Statfs_t Type: 16914836 
syscall.Statfs_t Bsize: 4096 
syscall.Statfs_t Blocks: 2560 

和DF:

$ df /dev/sda1 
Filesystem   1K-blocks  Used Available Use% Mounted on 
/dev/sda1    65792556 43694068 18726712 70% /var 

網:

  • os.Stat()0它不是,但可能是一個OS問題。
  • syscall.Statfs()給出2560塊* 4096塊大小= 10,485,760。更現實的,但仍然不正確
  • df給65792556 1K塊* 1024個字節/ K = 67,371,577,344

如何可靠地獲得一個塊設備的大小,而不安裝呢?

本質上,我正在尋找相當於設備上的ioctl呼叫。

ioctl(fd,BLKGETSIZE64,&size) 
+3

'os.Stat'返回'os.FileInfo'類型,是一個接口類型。 'Size'是返回類型的方法,而不是字段。 '0xc420031f58'是函數'Size'的地址。 https://golang.org/pkg/os/#FileInfo – abhink

+2

旁註:'fmt.Errorf'不是你所想的那樣。就像打印os.FileInfos Size字段一樣。如何查找所有使用的函數/方法的文檔? – Volker

+0

哦,哎呀。我應該做'Size()'。很好的接收。 – deitch

回答

5

當調用syscall.Statfs(),你必須通過路徑,其中設備被安裝,例如/,而不是設備文件(不是/dev/sda1)。在你的情況下,這是/var

您得到的結果值爲syscall.Statfs_t。解讀:

var stat syscall.Statfs_t 
if err := syscall.Statfs("/", &stat); err != nil { 
    panic(err) 
} 

size := stat.Blocks * uint64(stat.Bsize) 
free := stat.Bfree * uint64(stat.Bsize) 
avail := stat.Bavail * uint64(stat.Bsize) 
fmt.Println("Size:", size) 
fmt.Println("Free:", free) 
fmt.Println("Available:", avail) 
fmt.Println("Used:", size-free) 

看到這個可能重複:Get amount of free disk space using Go

+1

啊,非常好,謝謝@icza。那麼,我怎樣才能真正得到它_without_裝入?我可以在C中使用正確的'ioctl'調用(已編輯的問題),是否有一種本地方法? – deitch