os标准库
os包提供了操作系统函数,但和操作系统无关。
os包的接口规定为在所有操作系统中都是一致的。
设计为Unix风格的。
1. 权限说明
os标准库有大量的文件操作,在创建文件等操作中,需要指的perm。
在go语言中perm是一个uint32
类型
在go语言中一般使用0777这样的形式进行表示。
权限项 |
文件类型 |
读 |
写 |
执行 |
读 |
写 |
执行 |
读 |
写 |
执行 |
字符表示 |
(d|l|c|s|p) |
r |
w |
x |
r |
w |
x |
r |
w |
x |
数字表示 |
|
4 |
2 |
1 |
4 |
2 |
1 |
4 |
2 |
1 |
权限分配 |
|
文件所有者 |
文件所有者 |
文件所有者 |
文件所属组用户 |
文件所属组用户 |
文件所属组用户 |
其他用户 |
其他用户 |
其他用户 |
第一位:
-
: 代表这是一个普通文件(regular)
d
:目录文件(directory)
l
: 链接文件(link)
b
: 块设备文件(block)
c
: 字符设备文件(character)
s
: 套接字文件(socket)
p
: 管道文件(pipe)
一共有三组rwx
- 第一组:该文件拥有者的权限
- 第二组:该文件拥有者所在组的其他成员对该文件的操作权限
- 第三组:其他用户组的成员对该文件的操作权限
计算过程如下:
rwx |
rwx |
rwx |
111 |
111 |
111 |
7 |
7 |
7 |
go中的FileMode定义
FileMode代表文件的模式和权限位。这些字位在所有的操作系统都有相同的含义,因此文件的信息可以在不同的操作系统之间安全的移植。不是所有的位都能用于所有的系统,唯一共有的是用于表示目录的ModeDir位。
| const ( |
| |
| ModeDir FileMode = 1 << (32 - 1 - iota) |
| ModeAppend |
| ModeExclusive |
| ModeTemporary |
| ModeSymlink |
| ModeDevice |
| ModeNamedPipe |
| ModeSocket |
| ModeSetuid |
| ModeSetgid |
| ModeCharDevice |
| ModeSticky |
| |
| ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice |
| ModePerm FileMode = 0777 |
| ) |
这些被定义的位是FileMode最重要的位。另外9个不重要的位为标准Unix rwxrwxrwx权限(任何人都可读、写、运行)。这些(重要)位的值应被视为公共API的一部分,可能会用于线路协议或硬盘标识:它们不能被修改,但可以添加新的位。
2. os.Create
| func Create(name string) (file *File, err error) |
Create采用模式0666(任何人都可读写,不可执行)创建一个名为name的文件,如果文件已存在会截断它(为空文件)。如果成功,返回的文件对象可用于I/O;对应的文件描述符具有O_RDWR模式。
如果出错,错误底层类型是*PathError
| |
| func createFile() { |
| f, err := os.Create("test.txt") |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } else { |
| fmt.Printf("f: %v\n", f) |
| } |
| } |
| |
3. os.Mkdir
创建单个目录
| func Mkdir(name string, perm FileMode) error {} |
| func mkdir() { |
| err := os.Mkdir("ms", os.ModePerm) |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
| |
4. os.MkdirAll
创建多级目录
| func MkdirAll(path string, perm FileMode) error {} |
| func mkdirAll() { |
| err := os.MkdirAll("ms/one/two", os.ModePerm) |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
| |
5. os.Remove
删除一个空的目录或一个文件
| func Remove(name string) error {} |
| func removeFile() { |
| err := os.Remove("test.txt") |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
| func removeDir() { |
| err := os.Remove("ms/one/two") |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
6. os.RemoveAll
强制删除目录以及目录汇中的文件
| func RemoveAll(path string) error { |
| return removeAll(path) |
| } |
| |
| func removeAllDir() { |
| err := os.RemoveAll("ms") |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
| |
7. os.Getwd
获得工作目录
| func Getwd() (dir string, err error) {} |
| func getWd() { |
| dir, err := os.Getwd() |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } else { |
| fmt.Printf("dir: %v\n", dir) |
| } |
| } |
8. os.Chdir
修改工作目录
| |
| func (f *File) Chdir() error |
| func chDir() { |
| err := os.Chdir("d:/go/project") |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| fmt.Println(os.Getwd()) |
| } |
| |
9. os.TempDir
获得临时目录
| func TempDir() string { |
| return tempDir() |
| } |
| func tempDir() { |
| s := os.TempDir() |
| fmt.Printf("s: %v\n", s) |
| } |
10. os.Rename
重命名文件
| func Rename(oldpath, newpath string) error { |
| return rename(oldpath, newpath) |
| } |
| func renameFile() { |
| err := os.Rename("test.txt", "test2.txt") |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
| func renameDir() { |
| err := os.Rename("ms", "ms1") |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
11. os.Chmod
修改文件权限
| func Chmod(name string, mode FileMode) error { |
| return chmod(name, mode) |
| } |
| func chmod() { |
| err := os.Chmod("test2.txt", 0111) |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
打包linux测试
| SET CGO_ENABLED=0 |
| SET GOOS=linux |
| SET GOARCH=amd64 |
| go build main.go |
12. os.Chown
修改文件所有者
| func Chown(name string, uid, gid int) error {} |
cat /etc/passwd
查看uid和gid
| func chown() { |
| err := os.Chown("test2.txt", 10, 10) |
| if err != nil { |
| fmt.Printf("err: %v\n", err) |
| } |
| } |
13. 文件
打开模式
| 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_SYNC int = syscall.O_SYNC |
| O_TRUNC int = syscall.O_TRUNC |
| ) |
| |
| |
| func Create(name string) (file *File, err error) |
| |
| func Open(name string) (file *File, err error) |
| |
| func OpenFile(name string, flag int, perm FileMode) (file *File, err error) |
| |
| func (f *File) Close() error |
| |
其实os.Create
等价于:OpenFile(name, O_RDWF|O_CREATE|O_TRUNK, 0666)
| func openClose() { |
| f, err := os.OpenFile("test2.txt", os.O_RDWR|os.O_CREATE, 0755) |
| if err != nil { |
| panic(err) |
| } |
| fmt.Println("file name : ", f.Name()) |
| defer f.Close() |
| |
| } |
13.1 文件读取
| |
| func (f *File) Stat() (fi FileInfo, err error) |
| |
| func (f *File) Read(b []byte) (n int, err error) |
| |
| func (f *File) ReadAt(b []byte, off int64) (n int, err error) |
| |
| func ReadDir(name string) ([]DirEntry, error) |
| |
| func (f *File) Seek(offset int64, whence int) (ret int64, err error) |
| |
| type FileInfo interface { |
| Name() string |
| Size() int64 |
| Mode() FileMode |
| ModTime() time.Time |
| IsDir() bool |
| Sys() interface{} |
| } |
| |
| func fileStat() { |
| f, err := os.OpenFile("test2.txt", os.O_RDWR|os.O_CREATE, 0755) |
| if err != nil { |
| panic(err) |
| } |
| defer f.Close() |
| fileInfo, err := f.Stat() |
| if err != nil { |
| panic(err) |
| } |
| fmt.Printf("file info : %#v", fileInfo) |
| } |
| |
| func fileRead() { |
| f, err := os.OpenFile("test2.txt", os.O_RDWR|os.O_CREATE, 0755) |
| if err != nil { |
| panic(err) |
| } |
| defer f.Close() |
| var body []byte |
| for { |
| buf := make([]byte, 4) |
| n, err := f.Read(buf) |
| if err == io.EOF { |
| |
| break |
| } |
| fmt.Printf("读到的位置:%d \n", n) |
| body = append(body, buf[:n]...) |
| } |
| fmt.Printf("内容:%s \n", body) |
| } |
| |
| func fileReadAt() { |
| f, err := os.OpenFile("test2.txt", os.O_RDWR|os.O_CREATE, 0755) |
| if err != nil { |
| panic(err) |
| } |
| defer f.Close() |
| buf := make([]byte, 5) |
| n, err := f.ReadAt(buf, 6) |
| fmt.Printf("内容:%s \n", buf[:n]) |
| } |
| |
| func fileReadDir() { |
| f, err := os.Open("ms1") |
| if err != nil { |
| panic(err) |
| } |
| defer f.Close() |
| |
| dirs, err := f.ReadDir(-1) |
| if err != nil { |
| panic(err) |
| } |
| for _, v := range dirs { |
| fmt.Println("is dir:", v.IsDir()) |
| fmt.Println("dir name :", v.Name()) |
| } |
| } |
| |
| func fileSeek() { |
| f, err := os.OpenFile("test2.txt", os.O_RDWR|os.O_CREATE, 0755) |
| if err != nil { |
| panic(err) |
| } |
| defer f.Close() |
| f.Seek(3, 0) |
| buf := make([]byte, 10) |
| n, _ := f.Read(buf) |
| fmt.Printf("读取内容:%s\n", buf[:n]) |
| } |
| |
13.2 文件写
| |
| func (f *File) Write(b []byte) (n int, err error) |
| |
| func (f *File) WriteString(s string) (ret int, err error) |
| |
| func (f *File) WriteAt(b []byte, off int64) (n int, err error) |
| |
| func fileWrite() { |
| f, err := os.OpenFile("test2.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0755) |
| if err != nil { |
| panic(err) |
| } |
| defer f.Close() |
| f.Write([]byte("hello golang~\n")) |
| f.WriteString("hello golang~\n") |
| } |
| func fileWriteAt() { |
| f, err := os.OpenFile("test2.txt", os.O_RDWR|os.O_CREATE, 0755) |
| if err != nil { |
| panic(err) |
| } |
| defer f.Close() |
| _, err = f.WriteAt([]byte(" insert content~\n"), 5) |
| fmt.Println(err) |
| } |
14. 进程相关
| |
| func Exit(code int) |
| |
| func Getuid() int |
| |
| func Geteuid() int |
| |
| func Getgid() int |
| |
| func Getegid() int |
| |
| func Getgroups() ([]int, error) |
| |
| func Getpid() int |
| |
| func Getppid() int |
| |
| |
| func osInfo() { |
| |
| fmt.Println("---------") |
| fmt.Printf("os.Getpid(): %v\n", os.Getpid()) |
| |
| fmt.Printf("os.Getppid(): %v\n", os.Getppid()) |
| |
| |
| attr := &os.ProcAttr{ |
| |
| |
| Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, |
| |
| Env: os.Environ(), |
| } |
| |
| |
| p, err := os.StartProcess("c:\\windows\\system32\\notepad.exe", []string{"c:\\windows\\system32\\notepad.exe", "d:\\test.txt"}, attr) |
| if err != nil { |
| fmt.Println(err) |
| } |
| fmt.Println(p) |
| fmt.Println("进程ID:", p.Pid) |
| |
| |
| p2, _ := os.FindProcess(p.Pid) |
| fmt.Println(p2) |
| |
| |
| time.AfterFunc(time.Second*10, func() { |
| |
| p.Signal(os.Kill) |
| }) |
| |
| |
| ps, _ := p.Wait() |
| fmt.Println(ps.String()) |
| } |
type Signal
| type Signal interface { |
| String() string |
| Signal() |
| } |
Signal代表一个操作系统信号。一般其底层实现是依赖于操作系统的:在Unix中,它是syscall.Signal类型。
| var ( |
| Interrupt Signal = syscall.SIGINT |
| Kill Signal = syscall.SIGKILL |
| ) |
仅有的肯定会被所有操作系统提供的信号,Interrupt(中断信号)和Kill(强制退出信号)。
| 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") |
| ) |
Stdin、Stdout和Stderr是指向标准输入、标准输出、标准错误输出的文件描述符。
Args保管了命令行参数,第一个是程序名。
14.1 Signal
| |
| func main() { |
| go a() |
| go b() |
| ch := make(chan os.Signal) |
| signal.Notify(ch, os.Kill, os.Interrupt) |
| c := <-ch |
| log.Println(c) |
| } |
| |
| func b() { |
| fmt.Println("b") |
| } |
| |
| func a() { |
| fmt.Println("a") |
| } |
| |
15. 环境相关
| |
| func Hostname() (name string, err error) |
| |
| func Getenv(key string) string |
| |
| func Setenv(key, value string) error |
| |
| func Clearenv() |
| |
| |
| func osEnv() { |
| |
| s := os.Environ() |
| fmt.Printf("s: %v\n", s) |
| |
| s2 := os.Getenv("GOPATH") |
| fmt.Printf("s2: %v\n", s2) |
| |
| os.Setenv("env1", "env1") |
| s2 = os.Getenv("aaa") |
| fmt.Printf("s2: %v\n", s2) |
| fmt.Println("--------------") |
| |
| |
| s3, b := os.LookupEnv("env1") |
| fmt.Printf("b: %v\n", b) |
| fmt.Printf("s3: %v\n", s3) |
| |
| |
| |
| } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战