douhui3330 2017-10-04 07:00
浏览 119
已采纳

如何正确获取块设备的大小?

EDITED: as @abhink pointed out, was not invoking Size().

I tried two different go methods, and then compared to df. Of course, all 3 give different results:

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)
}

Running the programs:

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

And df:

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

Net:

  • os.Stat() gives 0 which it is not, but might be an OS issue.
  • syscall.Statfs() gives 2560 blocks * 4096 block size = 10,485,760. More realistic, but still incorrect
  • df gives 65792556 1K-blocks * 1024 bytes / K = 67,371,577,344

How do I reliably get the size of a block device without mounting it?

Essentially, I am looking for the equivalent of the ioctl call on the device.

ioctl(fd,BLKGETSIZE64,&size)
  • 写回答

2条回答 默认 最新

  • douzhi7070 2019-09-06 13:04
    关注

    The OP asked how to get the size of a block device. To get the size of a block device (or any file), you can File.Seek to the end of the file using io.SeekEnd and read the position returned. Credit to others for python and C.

    Running the example getsize.go below shows:

    $ sudo go run getsize.go /dev/sda
    /dev/sda is 256060514304 bytes.
    

    lsblk --bytes /dev/device will give you the same information. That is how much data the block device can store.

    The Statfs_t path, and df /path/to/mounted/filesystem will give you information about how much data you can store in the filesystem mounted at provided path. Filesystems have overhead, probably in the 2-5% range depending on details of the filesystem, and also keep track of how much space is Free or Used.

    There is no api that I am aware of that can provide information about unmounted filesystems on a block device. dumpe2fs can give you that information for the ext{2,3,4} filesystems. There likely exist tools for other filesystems. Such tools are filesystem specific. When you mount the filesystem, then the linux kernel's filesystem driver exposes that information that is returned by df.

    Code:

    // getsize.go: get the size of a block device or file
    package main
    
    import (
        "fmt"
        "io"
        "os"
    )
    
    func main() {
        var path string
        if len(os.Args) < 2 {
            fmt.Println("Give path to file/disk")
            os.Exit(1)
        }
        path = os.Args[1]
        file, err := os.Open(path)
        if err != nil {
            fmt.Printf("error opening %s: %s
    ", path, err)
            os.Exit(1)
        }
        pos, err := file.Seek(0, io.SeekEnd)
        if err != nil {
            fmt.Printf("error seeking to end of %s: %s
    ", path, err)
            os.Exit(1)
        }
        fmt.Printf("%s is %d bytes.
    ", path, pos)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算