注册 登录

清河洛

Go语言中的os包

qingheluo2021-09-10清河洛392
os包提供了操作系统函数的接口os包的接口对各种操作系统的差异做了统一的包装,在所有操作系统中都是一致的,本身设计为Unix风格如常量DevNull,在类似Unix的操作系统中为"/dev/null",在Windows中为"NUL",我们使用时不需要关系具体的操作系统,只需要使用常量DevNull即可所以os包不依赖平台公用常量const ( PathSeparator = ‘/‘ // 操作系统指定的路径分隔符 PathListSeparator = ‘:‘ // 操作系统指定的表分隔符 ) os包中的变量var ( ErrInvalid = er...

os包提供了操作系统函数的接口

os包的接口对各种操作系统的差异做了统一的包装,在所有操作系统中都是一致的,本身设计为Unix风格

如常量DevNull,在类似Unix的操作系统中为"/dev/null",在Windows中为"NUL",我们使用时不需要关系具体的操作系统,只需要使用常量DevNull即可

所以os包不依赖平台

公用常量

const (
    PathSeparator     = ‘/‘ // 操作系统指定的路径分隔符
    PathListSeparator = ‘:‘ // 操作系统指定的表分隔符
)

os包中的变量

var (
    ErrInvalid    = errors.New("invalid argument")
    ErrPermission = errors.New("permission denied")
    ErrExist      = errors.New("file already exists")
    ErrNotExist   = errors.New("file does not exist")
)
一些可移植的、共有的系统调用错误

var (
    Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
    Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
    Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)
指向标准输入、标准输出、标准错误输出的文件描述符

var Args []string :切片Args保管了命令行参数,第一个是程序名

系统相关信息

Hostname() (name string, err error) :获取内核提供的主机名
Getpagesize() int :返回底层的系统内存页的尺寸,簇大小
Environ() []string :返回以"key=value"表示环境变量的字符串切片拷贝
Getenv(key string) string :返回名为key的环境变量的值。如果不存返回空字符串
Setenv(key, value string) error :设置名为key的环境变量
Clearenv() :删除所有环境变量
Exit(code int) :以指定状态码退出。0表示成功,非0表示出错。程序会立刻终止,defer的函数不会被执行
Expand(s string, mapping func(string) string) string :
    替换s中的${var}或$var为mapping(var)
    省略第二个参数默认使用函数os.Getenv
ExpandEnv(s string) string :
    替换s中的${var}或$var为名为var的环境变量的值
    如果环境变量不存在会替换为空字符串
Getuid() int :返回调用者的用户ID
Geteuid() int :返回调用者的有效用户ID
Getgid() int :返回调用者的组ID
Getegid() int :返回调用者的有效组ID
Getgroups() ([]int, error) :返回调用者所属的所有用户组的组ID
Getpid() int :返回调用者所在进程的进程ID
Getppid() int :返回调用者所在进程的父进程的进程ID

模式和权限位

type FileMode uint32
const (
    // 单字符是被String方法用于格式化的属性缩写。
    ModeDir        FileMode = 1 << (32 - 1 - iota) // d: 目录
    ModeAppend                                     // a: 只能写入,且只能写入到末尾
    ModeExclusive                                  // l: 用于执行
    ModeTemporary                                  // T: 临时文件(非备份文件)
    ModeSymlink                                    // L: 符号链接(不是快捷方式文件)
    ModeDevice                                     // D: 设备
    ModeNamedPipe                                  // p: 命名管道(FIFO)
    ModeSocket                                     // S: Unix域socket
    ModeSetuid                                     // u: 表示文件具有其创建者用户id权限
    ModeSetgid                                     // g: 表示文件具有其创建者组id的权限
    ModeCharDevice                                 // c: 字符设备,需已设置ModeDevice
    ModeSticky                                     // t: 只有root/创建者能删除/移动文件
    // 覆盖所有类型位(用于通过&获取类型位),对普通文件,所有这些位都不应被设置
    ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
    ModePerm FileMode = 0777 // 覆盖所有Unix权限位(用于通过&获取类型位)
)
这些被定义的位是FileMode最重要的位,表示文件的文件模式(类型),权限位默认为"rwxrwxrwx"

(m FileMode) IsDir() bool :判断m是否是一个目录
(m FileMode) IsRegular() bool :判断m是否是一个普通文件
(m FileMode) Perm() FileMode:返回m的Unix权限位
(m FileMode) String() string:将m的文件模式和权限位转换为字符串

文件信息

FileInfo接口用来描述一个文件对象
type FileInfo interface {
    Name() string       // 文件的名字(不含扩展名)
    Size() int64        // 普通文件返回值表示其大小;其他文件的返回值含义各系统不同
    Mode() FileMode     // 文件的模式位
    ModTime() time.Time // 文件的修改时间
    IsDir() bool        // 等价于Mode().IsDir()
    Sys() interface{}   // 底层数据来源(可以返回nil)
}

Stat(name string) (fi FileInfo, err error):
    返回一个描述name指定的文件对象的FileInfo
    如果文件为符号链接,返回的FileInfo描述该符号链接指向的文件的信息
    函数会尝试跳转该链接
Lstat(name string) (fi FileInfo, err error):
    功能与Stat函数相同,不同的是不会尝试跳转该链接
IsPathSeparator(c uint8) bool :判断字符c是否是一个路径分隔符
IsExist(err error) bool :指定错误是否表示一个文件或目录已经存在
IsNotExist(err error) bool :指定错误是否表示一个文件或目录不存在
IsPermission(err error) bool :定错误是否是因权限不足要求被拒绝
Getwd() (dir string, err error) :返回当前工作目录的根路径
Chdir(dir string) error :将当前工作目录修改为dir指定的目录
Chmod(name string, mode FileMode) error :修改name指定的文件对象(符号链接会修改最终文件)的mode
Chown(name string, uid, gid int) error :修改name指定的文件对象(符号链接会修改最终文件)的用户id和组id
Lchown(name string, uid, gid int) error : 同Chown函数,不同发是符号链接会修改符号链接本身
Chtimes(name string, atime time.Time, mtime time.Time) error :修改name指定的文件对象的访问时间和修改时间
Mkdir(name string, perm FileMode) error :使用指定的权限和名称创建一个目录
MkdirAll(path string, perm FileMode) error :使用指定的权限和名称递归创建一个目录
MkdirTemp(dir, pattern string) (string, error)
    在目录dir中创建一个根据pattern生成的含有随机字符串的临时目录,并返回生成目录的路径名
    如果dir是空字符串,则使用os.TempDir()返回的值
    如果pattern中包含星号(*),则随机字符串替换最后一个星号
    如果pattern中不包含星号(*),则在末尾添加随机字符串
    目录创建的程序有责任在不再需要目录时将其删除
Rename(oldpath, newpath string) error :修改或移动一个文件的名称
Truncate(name string, size int64) error :修改name指定的文件(符号链接会修改最终文件)的大小
Remove(name string) error :删除name指定的文件或目录
RemoveAll(path string) error :
    删除path指定的文件,或目录及它包含的任何下级对象
    如果path指定的对象不存在,RemoveAll会返回nil而不返回错误
Readlink(name string) (string, error) :获取name指定的符号链接文件指向的文件的路径
Symlink(oldname, newname string) error :创建一个名为newname指向oldname的符号链接
Link(oldname, newname string) error :创建一个名为newname指向oldname的硬链接
SameFile(fi1, fi2 FileInfo) bool :返回fi1和fi2是否在描述同一个文件
TempDir() string :返回一个用于保管临时文件的默认目录

文件操作

const (
    O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
    O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
    O_RDWR   int = syscall.O_RDWR   // 读写模式打开文件
    O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
    O_CREATE int = syscall.O_CREAT  // 如果不存在将创建一个新文件
    O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用,文件必须不存在
    O_SYNC   int = syscall.O_SYNC   // 打开文件用于同步I/O
    O_TRUNC  int = syscall.O_TRUNC  // 如果可能,打开时清空文件
)
用于包装底层系统的参数用于Open函数,不是所有的flag都能在特定系统里使用的

type File struct {
    // 内含隐藏或非导出字段
}
File代表一个打开的文件对象

Create(name string) (file *File, err error) :
    以0666权限模式创建name文件
    如果文件已存在会截断它(为空文件)
    返回的文件描述符具有O_RDWR模式
Open(name string) (file *File, err error) :
    打开一个文件用于读取
    返回的文件描述符具有O_RDONLY模式
OpenFile(name string, flag int, perm FileMode) (file *File, err error) :
    使用指定的选项flag(如O_RDONLY)、指定的模式(如0666等)打开指定名称的文件
Pipe() (r *File, w *File, err error) :返回一对关联的文件对象。从r的读取将返回写入w的数据

(f *File) Name() string :返回一个文件对象的名称
(f *File) Stat() (fi FileInfo, err error) :返回描述文件f的FileInfo类型值
(f *File) Chdir() error :将当前工作目录修改为f,f必须是一个目录
(f *File) Chmod(mode FileMode) error :修改文件的模式
(f *File) Chown(uid, gid int) error :修改文件的用户ID和组ID
(f *File) Readdir(n int) (fi []FileInfo, err error) :
    读取目录f下包含的文件并返回文件的FileInfo组成的切片
    这些FileInfo是被Lstat返回的,采用目录顺序
    当n>0时:
        会返回一个最多n个成员的切片
        在此调用本函数会返回上一次调用剩余未读取的文件信息
        如果Readdir返回一个空切片,它会返回一个非nil的错误说明原因
        如果到达了目录f的结尾,返回值err会是io.EOF
    当n<=0时:
        返回目录中剩余所有文件对象的FileInfo构成的切片
(f *File) Readdirnames(n int) (names []string, err error) :
    返回目录f下包含的文件并返回文件的名称组成的切片
    用法和Readdir相同
(f *File) Truncate(size int64) error :截断文件从而达到指定的文件大小
(f *File) Read(b []byte) (n int, err error) :
    从f中读取最多len(b)字节数据并写入b
    文件终止标志是读取0个字节且返回值err为io.EOF
    主要用于分块读取,可在速度和内存占用之间取得很好的平衡
    demo,_ := os.Open("测试.txt")
    buf := make([]byte, 15) //每次读取的大小
    data := ""
    for{
        _,err := demo.Read(buf)
        if err == io.EOF {
            break
        }
        data = data + string(buf)
    }
    fmt.Println(data)
想要读取一个文件的全部内容我们可以使用io/ioutil包中的ioutil.ReadAll(f *File)来读取
(f *File) Write(b []byte) (n int, err error) :向文件中写入字节切片数据
(f *File) WriteString(s string) (ret int, err error) :向文件中写入字符串数据

(f *File) Seek(offset int64, whence int) (ret int64, err error)
    设置下一次读/写的位置
    offset为相对偏移量
    whence决定相对位置,0为文件开头,1为当前位置,2为文件结尾
    返回新的偏移量(相对开头)和可能的错误
    const (
        SEEK_SET int = 0 // 相对于文件起始位置seek
        SEEK_CUR int = 1 // 相对于文件当前位置seek
        SEEK_END int = 2 // 相对于文件结尾位置seek
    )
(f *File) Sync() (err error) :将文件系统的最近写入的数据在内存中的拷贝刷新到硬盘中稳定保存
(f *File) Close() error :关闭文件f,使文件不能用于读写

进程文件

type ProcAttr struct {
    // 如果Dir非空,子进程会在创建进程前先进入该目录。(即设为当前工作目录)
    Dir string
    // 如果Env非空,它会作为新进程的环境变量。必须采用Environ返回值的格式。
    // 如果Env为空字符串,将使用Environ函数的返回值。
    Env []string
    // Files指定被新进程继承的活动文件对象。
    // 前三个绑定为标准输入、标准输出、标准错误输出。
    // 依赖底层操作系统的实现可能会支持额外的数据出入途径。
    // nil条目相当于在进程开始时关闭的文件对象。
    Files []*File
    // 操作系统特定的创建属性。
    // 注意设置本字段意味着你的程序可能会运作失常甚至在某些操作系统中无法通过编译。
    Sys *syscall.SysProcAttr
}
ProcAttr保管将被StartProcess函数用于一个新进程的属性

type Process struct {
    Pid int
    // 内含隐藏或非导出字段
}
Process保管一个被StarProcess创建的进程的信息

type Signal interface {
    String() string
    Signal() // 用来区分其他实现了Stringer接口的类型
}
Signal代表一个操作系统信号

var (
    Interrupt Signal = syscall.SIGINT
    Kill      Signal = syscall.SIGKILL
)
Interrupt(中断信号)和Kill(强制退出信号)

FindProcess(pid int) (p *Process, err error) :根据进程id查找一个运行中的进程。返回进程对象
StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error):使用提供的程序名、命令行参数、属性开始一个新进程
(p *Process) Signal(sig Signal) error :向进程发送一个信号
(p *Process) Kill() error :让进程强制立刻退出
(p *Process) Wait() (*ProcessState, error) :
    阻塞直到进程退出并释放绑定到进程p的所有资源
    返回一个描述进程的状态和可能的错误
    在大多数操作系统中,进程p必须是当前进程的子进程
(p *Process) Release() error :释放进程p绑定的所有资源,只有没有调用Wait方法时才需要调用本方法
type ProcessState struct {} 保管Wait函数报告的某个已退出进程的信息
(p *ProcessState) Pid() int :返回一个已退出的进程的进程id
(p *ProcessState) Exited() bool :报告进程是否已退出
(p *ProcessState) Success() bool :报告进程是否成功退出,退出码是否为0
(p *ProcessState) SystemTime() time.Duration :返回已退出进程及其子进程耗费的系统CPU时间
(p *ProcessState) UserTime() time.Duration :返回已退出进程及其子进程耗费的用户CPU时间
(p *ProcessState) Sys() interface{} :
    返回已退出进程系统特定的退出信息
    需要将其类型转换为适当的底层类型,如Unix里转换为*syscall.WaitStatus类型以获取其内容
(p *ProcessState) SysUsage() interface{} :
    返回该已退出进程系统特定的资源使用信息
    需要将其类型转换为适当的底层类型,如Unix里转换为*syscall.Rusage类型以获取其内容
(p *ProcessState) String() string

执行系统命令

Go的"os/exec"包用于执行外部命令,它包装了os.StartProcess函数以便更容易的修正输入和输出,使用管道连接I/O,以及作其它的一些调整

包级导出函数

LookPath(file string) (string, error)
    在环境变量PATH指定的目录中搜索可执行文件
    如file中有路径分隔符,则只在指定目录搜索
    返回file的绝对路径

"os/exec"包主要设定了一个Cmd结构体,用于存储执行命令的相关参数以及定义执行命令的相关操作方法

type Cmd struct {
    Path string
        // 要执行命令的路径
        // 该字段是唯一不能为空的字段
        // 相对路径会相对于Dir字段
    Args []string
        // 命令的参数,包括命令名作为第一个参数
        // 如果为空切片或者nil,将使用Path值
    Env []string
        // 指定进程的环境,为nil表示当前进程的环境
        // 每个条目的格式都是“key=value”
        // 如果包含重复键则使用最后一个值
        // 在windows中,如果没有明确设置为空字符串,则始终自动添加SYSTEMROOT环境变量键值对
    Dir string
        // 命令的工作目录。为空表示进程所在目录
    Stdin io.Reader
    Stdout io.Writer
    Stderr io.Writer
        // 进程标准输入、输出和错误输出,为nil表示空设备(os.DevNull)
        // 如果标准输出和错误输出相同,同一时间最多有一个线程可以写入
    ExtraFiles []*os.File
        // 指定额外被新进程继承的已打开文件流,不包括标准输入、标准输出、标准错误输出
        // 如果本字段非nil,entry i会变成文件描述符3+i
        // windows系统不支持该字段
    SysProcAttr *syscall.SysProcAttr
        // 可选的、各操作系统特定的sys执行属性
        // 会将它作为os.ProcAttr的Sys字段传递给os.StartProcess函数
    Process *os.Process
        // 底层的,只执行一次的进程
    ProcessState *os.ProcessState
        // 已退出进程的信息,命令完成时填充其ProcessState
        // 只有在调用Wait或Run后才可用
    Err error // LookPath错误
    Cancel func() error
        // 如果非nil,则该Cmd必须是使用CommandContext创建的
        // 当Context完成时,将在满足WaitDelay的情况下调用Cancel
        // Cancel为nil默认会调用Process上的Kill方法
        // 如果Start返回非nil错误,则不会调用Cancel
    WaitDelay time.Duration
        // 在上下文被取消 或 Wait后子进程退出但其I/O管道未关闭
        // 以上两个条件以先发生为准
        // 当延迟结束时,会关闭子进程或其I/O管道
        // 如果管道因WaitDelay而关闭但没有发生Cancel调用,Wait和类似方法将返回ErrWaitDelay,而不是nil
}

Cmd在调用其Run、Output或CombinedOutput方法后不能重用

创建Cmd

Command(name string, arg ...string) *Cmd
    创建一个name为命令名,arg为不含命令名的运行参数的CMD
    如果name不含路径分隔符,将使用LookPath获取完整路径,否则直接使用name

CommandContext(ctx context.Context, name string, arg ...string) *Cmd
    创建一个包含上下文的Cmd
    如果上下文在命令完成之前完成,则提供的上下文用于中断进程(通过调用cmd.Cancel或os.Process.Kill)
    设置命令的Cancel函数以调用其Process上的Kill方法,并保持其WaitDelay未设置
    调用者可以通过在启动命令之前修改这些字段来更改取消行为

Cmd的常用方法

String() string :返回Cmd的字符串描述,仅用于调试,不可用于shell的输入

Run() error   :执行命令并阻塞直到完成

Start() error :执行命令但不等待命令完成就立即返回
    如果成功返回,则将设置c.Process字段
    成功调用后必须调用Wait方法以释放关联的系统资源

Wait() error  :阻塞直到命令执行完成
    Cmd必须是已被Start方法开始执行的
    Wait会在命令返回后释放与Cmd关联的所有资源

Output() ([]byte, error) :执行命令并返回标准输出

CombinedOutput() ([]byte, error) :执行命令并返回标准输出和错误输出合并后的输出

Environ() []string  :返回命令运行环境的副本

StdinPipe() (io.WriteCloser, error) :返回在命令Start后与标准输入关联的管道,Wait方法获知命令结束后会关闭这个管道

StdoutPipe() (io.ReadCloser, error) :返回在命令Start后与标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道
    但是在从管道读取完全部数据之前调用Wait是错误的
    同样使用StdoutPipe方法时调用Run函数也是错误的

 StderrPipe() (io.ReadCloser, error):返回在命令Start后与标准错误输出关联的管道。Wait方法获知命令结束后会关闭这个管道
    但是在从管道读取完全部数据之前调用Wait是错误的
    同样使用StderrPipe方法时调用Run函数也是错误的


网址导航