douhui3330 2017-10-03 23: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 05: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条)
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 关于#c##的问题:treenode反序列化后获取不到上一节点和下一节点,Fullpath和Handle报错
  • ¥15 一部手机能否同时用不同的app进入不同的直播间?
  • ¥15 没输出运行不了什么问题
  • ¥20 输入import torch显示Intel MKL FATAL ERROR,系统驱动1%,: Cannot load mkl_intel_thread.dll.
  • ¥15 点云密度大则包围盒小
  • ¥15 nginx使用nfs进行服务器的数据共享
  • ¥15 C#i编程中so-ir-192编码的字符集转码UTF8问题
  • ¥15 51嵌入式入门按键小项目
  • ¥30 海外项目,如何降低Google Map接口费用?
  • ¥15 fluentmeshing