在实际的项目开发中,我们可能需要根据运行环境的不同来编译不同的文件.
Golang 支持两种条件编译方式:
两者可以结合起来使用。
Go使用 go/build包 中定义的标签系统(system of tags)和命名约定(naming convention)以及go tool中的相应支持来允许Go包编译特定代码。
说简单的,就是通过约定好的规定,在执行go build 选择性地包含或排除代码的机制。
注意,go1.17 过后,条件编译的写法和之前有些不同,需要注意一下。
当Go编译一个包时,它会分析包内的每个源码文件并查找构建标签。标签决定了这个源码文件是否被编译。条件编译的最小单元是以 文件 来进行的。
构建约束以一行+build开始的注释。在+build之后列出了一些条件,在这些条件成立时,该文件应包含在编译的包中;
约束可以出现在任何源文件中,不限于go文件;
+build必须出现在package语句之前,+build注释之后应要有一个空行,否则不会生效。
这种方案比构造标签方案更简单。
如果文件名包含_KaTeX parse error: Expected group after '_' at position 49: …台会忽略这个文件。另一种约定是_?GOARCH.go。这两种后缀可以组合起来,但要保证顺序,正确的格式是_KaTeX parse error: Expected group after '_' at position 5: GOOS_?GOARCH.go,错误的格式是_KaTeX parse error: Expected group after '_' at position 7: GOARCH_?GOOS.go。
如果使用的是 goland 当在 windows 上面新建文件名为 xxxx_linux.go时,goland 会自动提示 tag_linux.go is ignored by the build tool because of the OS mismatch。
GO golang 获取磁盘空间 条件编译
参考URL: https://www.jianshu.com/p/f3d31f84d95d
思路: 根据不同的操作系统创建不同的文件,并使用条件编译指令来选择相应的文件进行编译
首先,创建 disc_space_linux.go
文件,用于 Linux 系统的实现
获取磁盘占用情况(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
}
然后,创建 disc_space_windows.go
文件,用于 Windows 系统的实现
windows好像不用判断某个目录占用和剩余空间大小,直接判断这个目录所在的盘符占用空间多少,剩余空间多少就行。
package utils
import "unsafe"
import (
"golang.org/x/sys/windows"
)
type DiskStatus struct {
All uint64
Used uint64
Free uint64
}
func DiskUsage(path string) (disk DiskStatus) {
h := windows.MustLoadDLL("kernel32.dll")
c := h.MustFindProc("GetDiskFreeSpaceExW")
lpFreeBytesAvailable := uint64(0)
lpTotalNumberOfBytes := uint64(0)
lpTotalNumberOfFreeBytes := uint64(0)
r1, r2, err := c.Call(uintptr(unsafe.Pointer(windows.StringToUTF16Ptr("C:"))),
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
disk.All = lpTotalNumberOfBytes
disk.Free = lpTotalNumberOfFreeBytes
disk.Used = lpFreeBytesAvailable
return
}
在这个示例中,根据不同的操作系统,分别创建了 disc_space_linux.go 和 disc_space_windows.go 两个文件,并使用条件编译指令来选择相应的文件进行编译。
https://github.com/shirou/gopsutil
Go中获取磁盘空间信息,你可以使用第三方库 github.com/shirou/gopsutil/disk
这个库提供了一个跨平台的方法来获取磁盘的使用情况。
gopstuil就是go语言版的psutil,pstuil字面意思是进程和系统实用程序。
gopsutil的挑战在于将pstuil上的函数移植到不同的架构上。所有的通过将C结构体移植到Go结构体来实现,没有cgo。目前支持的架构:
FreeBSD i386/amd64/arm
Linux i386/amd64/arm(raspberry pi)
Windows i386/amd64/arm/arm64
Darwin amd64/arm64
OpenBSD amd64
Solaris amd64
func getDiskUsage(path string) (uint64, uint64, error) {
//disk.Usage() 函数来获取指定路径的磁盘使用情况
usage, err := disk.Usage(path)
if err != nil {
return 0, 0, err
}
usedSpace := usage.Used
freeSpace := usage.Free
return usedSpace, freeSpace, nil
}