权限perm,在创建文件时才需要指定,不需要创建新文件时可以将其设定为0。虽然go语言给perm权限设定了很多的常量,但是习惯上也可以直接使用数字,如0666(具体含义和Unix系统的一致)。
权限项 | 文件类型 | 读 | 写 | 执行 | 读 | 写 | 执行 | 读 | 写 | 执行 |
---|---|---|---|---|---|---|---|---|---|---|
字符表示 | (d|l|c|s|p) | r | w | x | r | w | x | r | w | x |
数字表示 | 4 | 2 | 1 | 4 | 2 | 1 | 4 | 2 | 1 | |
权限分配 | 文件所有者 | 文件所有者 | 文件所有者 | 文件所属组用户 | 文件所属组用户 | 文件所属组用户 | 其他用户 | 其他用户 | 其他用户 |
关于- rwx rwx rwx
:
-
:代表这是一个普通文件(regular), 其中其他文件类型还包括了
d--------->目录文件(directory)
l --------->链接文件(link)
b--------->块设备文件(block)
c--------->字符设备文件(character)
s--------->套接字文件(socket)
p--------->管道文件(pipe)
一共有三组rwx(下图中的每一个框起来的rwx对应一组用户权限),分别是以下几种用户的rwx权限:
第一组:该文件拥有者的权限
第二组:该文件拥有者所在组的其他成员对该文件的操作权限
第三组:其他用户组的成员对该文件的操作权限
注意在这里计算权限的值是使用八进制进行计算的;例如上图中的-rwxrwxrwx
(前面的-代表这是一个普通文件)文件权限,我们计算过程如下:
rwx | rwx | rwx |
---|---|---|
111 | 111 | 111 |
7 | 7 | 7 |
此时该文件的权限值为0777,当然还有0666、0755等都是这么得来的
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)
}
}
func Mkdir(name string, perm FileMode) error {}
只能创建单个目录,不能创建多级目录
实例演示:
func createDir1() {
err := os.Mkdir("test", os.ModePerm)
if err != nil {
fmt.Printf("err: %v\n", err)
}
}
func MkdirAll(path string, perm FileMode) error {}
实例演示:
func createDir2() {
err := os.MkdirAll("test/a/b", os.ModePerm)
if err != nil {
fmt.Printf("err: %v\n", err)
}
}
func Remove(name string) error {}
实例演示:
func removeDir1() {
err := os.Remove("test.txt")
if err != nil {
fmt.Printf("err: %v\n", err)
}
}
func RemoveAll(path string) error {
return removeAll(path)
}
实例演示:
func removeDir2() {
err := os.RemoveAll("test")
if err != nil {
fmt.Printf("err: %v\n", err)
}
}
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)
}
}
func (f *File) Chdir() error
改变工作目录到f,其中f必须为一个目录,否则便会报错
实例演示:
func chWd() {
err := os.Chdir("d:/")
if err != nil {
fmt.Printf("err: %v\n", err)
}
fmt.Println(os.Getwd())
}
func TempDir() string {
return tempDir()
}
实例演示:
func getTemp() {
s := os.TempDir()
fmt.Printf("s: %v\n", s)
}
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 Chmod(name string, mode FileMode) error {
return chmod(name, mode)
}
func Chown(name string, uid, gid int) error {}
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 // 如果可能,打开时清空文件
)
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)
实例演示:
package main
import (
"fmt"
"os"
)
func openCloseFile() {
// 只能读
f, _ := os.Open("a.txt")
fmt.Printf("f.Name(): %v\n", f.Name())
// 根据第二个文件打开模式参数 可以指定权限为读写或者创建
f2, _ := os.OpenFile("a1.txt", os.O_RDWR|os.O_CREATE, 0755)
fmt.Printf("f2.Name(): %v\n", f2.Name())
err := f.Close()
fmt.Printf("err: %v\n", err)
err2 := f2.Close()
fmt.Printf("err2: %v\n", err2)
}
func main() {
openCloseFile()
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
f.Name(): a.txt
f2.Name(): a1.txt
err: <nil>
err2: <nil>
[Done] exited with code=0 in 0.806 seconds
func (f *File) Stat() (fi FileInfo, err error) // 获取文件的信息,里面有文件的名称,大小,修改时间等
func (f *File) Read(b []byte) (n int, err error) // 从文件中一次性读取b大小的数据,当读到文件结尾时,返回一个EOF错误
func (f *File) ReadAt(b []byte, off int64) (n int, err error) // 从文件中指定的位置(off)一次性读取b大小的数据
func ReadDir(name string) ([]DirEntry, error) // 读取目录并返回排好序的文件以及子目录名切片
func (f *File) Seek(offset int64, whence int) (ret int64, err error)
//Seek设置下一次读/写的位置。offset为相对偏移量,而whence决定相对位置:0为相对文件开头,1为相对当前位置,2为相对文件结尾。它返回新的偏移量(相对开头)和可能的错误。
下述实例演示其中a.txt内容为:
hello world
package main
import (
"fmt"
"io"
"os"
)
func main() {
f, _ := os.Open("a.txt")
for {
buf := make([]byte, 4) // 设置一个缓冲区,一次读4个字节
n, err := f.Read(buf) // 将读到的内容放入缓冲区内
fmt.Printf("string(buf): %v\n", string(buf))
fmt.Printf("n: %v\n", n)
if err == io.EOF { // EOF表示文件读取完毕
break
}
}
f.Close()
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
string(buf): hell
n: 4
string(buf): o wo
n: 4
string(buf): rld
[Done] exited with code=0 in 0.998 seconds
package main
import (
"fmt"
"os"
)
func main() {
buf := make([]byte, 10)
f2, _ := os.Open("a.txt")
// 从5开始读10个字节
n, _ := f2.ReadAt(buf, 5)
fmt.Printf("n: %v\n", n)
fmt.Printf("string(buf): %v\n", string(buf))
f2.Close()
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
n: 6
string(buf): world
[Done] exited with code=0 in 0.961 seconds
package main
import (
"fmt"
"os"
)
func main() {
// 测试 a目录下有b和c目录
f, _ := os.Open("a")
de, _ := f.ReadDir(-1) // 返回一个切片de
for _, v := range de {
fmt.Printf("v.IsDir(): %v\n", v.IsDir())
fmt.Printf("v.Name(): %v\n", v.Name())
}
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
v.IsDir(): true
v.Name(): b
v.IsDir(): true
v.Name(): c
[Done] exited with code=0 in 0.963 seconds
package main
import (
"fmt"
"os"
)
func main() {
f, _ := os.Open("a.txt") // 打开文件后,光标默认在文件开头
f.Seek(3, 0) // 从索引值为3处开始读
buf := make([]byte, 10) // 设置缓冲区
n, _ := f.Read(buf) // 将内容读到缓冲区内
fmt.Printf("n: %v\n", n)
fmt.Printf("string(buf): %v\n", string(buf))
f.Close()
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
n: 8
string(buf): lo world
[Done] exited with code=0 in 0.86 seconds
package main
import (
"fmt"
"os"
)
func main() {
f, _ := os.Open("a.txt") // 打开文件后,光标默认在文件开头
fInfo, _ := f.Stat()
fmt.Printf("f是否是一个文件: %v\n", fInfo.IsDir())
fmt.Printf("f文件的修改时间: %v\n", fInfo.ModTime().String())
fmt.Printf("f文件的名称: %v\n", fInfo.Name())
fmt.Printf("f文件的大小: %v\n", fInfo.Size())
fmt.Printf("f文件的权限: %v\n", fInfo.Mode().String())
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
f是否是一个文件: false
f文件的修改时间: 2022-07-08 13:30:53.059132 +0800 CST
f文件的名称: a.txt
f文件的大小: 11
f文件的权限: -rw-rw-rw-
[Done] exited with code=0 in 1.008 seconds
func (f *File) Write(b []byte) (n int, err error)
//Write向文件中写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。
func (f *File) WriteString(s string) (ret int, err error)
//WriteString类似Write,但接受一个字符串参数。
func (f *File) WriteAt(b []byte, off int64) (n int, err error)
//WriteAt在指定的位置(相对于文件开始位置)写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。
下述实例演示其中a.txt内容为:
hello world
package main
import (
"os"
)
func main() {
f, _ := os.OpenFile("a.txt", os.O_RDWR|os.O_APPEND, 0775) // 以读写模式打开文件,并且在写操作时将数据附加到文件尾部
f.Write([]byte(" hello golang"))
f.Close()
}
运行结果:
hello world hello golang
package main
import (
"os"
)
func main() {
f, _ := os.OpenFile("a.txt", os.O_RDWR|os.O_TRUNC, 0775) // 以读写模式打开文件,并且打开时清空文件
f.WriteString("hello world...")
f.Close()
}
运行结果:
hello world...
package main
import (
"os"
)
func main() {
f, _ := os.OpenFile("a.txt", os.O_RDWR, 0775) // 以读写模式打开文件
f.WriteAt([]byte("aaa"), 3) // 从索引值为3的地方开始写入aaa并覆盖原来当前位置的数据
f.Close()
}
运行结果:
heaaa world
func Exit(code int) // 让当前程序以给出的状态码(code)退出。一般来说,状态码0表示成功,非0表示出错。程序会立刻终止,defer的函数不会被执行。
func Getuid() int // 获取调用者的用户id
func Geteuid() int // 获取调用者的有效用户id
func Getgid() int // 获取调用者的组id
func Getegid() int // 获取调用者的有效组id
func Getgroups() ([]int, error) // 获取调用者所在的所有组的组id
func Getpid() int // 获取调用者所在进程的进程id
func Getppid() int // 获取调用者所在进程的父进程的进程id
实例演示:
package main
import (
"fmt"
"os"
"time"
)
func main() {
// 获得当前正在运行的进程id
fmt.Printf("os.Getpid(): %v\n", os.Getpid())
// 父id
fmt.Printf("os.Getppid(): %v\n", os.Getppid())
// 设置新进程的属性
attr := &os.ProcAttr{
// files指定新进程继承的活动文件对象
// 前三个分别为,标准输入、标准输出、标准错误输出
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:\\a.txt"}, attr)
if err != nil {
fmt.Println(err)
}
fmt.Println(p)
fmt.Println("进程ID:", p.Pid)
// 通过进程ID查找进程
p2, _ := os.FindProcess(p.Pid)
fmt.Println(p2)
// 等待10秒,执行函数
time.AfterFunc(time.Second*10, func() {
// 向p进程发出退出信号
p.Signal(os.Kill)
})
// 等待进程p的退出,返回进程状态
ps, _ := p.Wait()
fmt.Println(ps.String())
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
os.Getpid(): 5440
os.Getppid(): 8216
&{9768 348 0 {{0 0} 0 0 0 0}}
进程ID: 9768
&{9768 324 0 {{0 0} 0 0 0 0}}
exit status 0
[Done] exited with code=0 in 2.9 seconds
unc Hostname() (name string, err error) // 获取主机名
func Getenv(key string) string // 获取某个环境变量
func Setenv(key, value string) error // 设置一个环境变量,失败返回错误,经测试当前设置的环境变量只在 当前进程有效(当前进程衍生的所以的go程都可以拿到,子go程与父go程的环境变量可以互相获取);进程退出消失
func Clearenv() // 删除当前程序已有的所有环境变量。不会影响当前电脑系统的环境变量,这些环境变量都是对当前go程序而言的
实例演示:
package main
import (
"fmt"
"os"
)
func main() {
// 获得所有环境变量
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("env")
fmt.Printf("b: %v\n", b)
fmt.Printf("s3: %v\n", s3)
// 替换
os.Setenv("NAME", "gopher")
os.Setenv("BURROW", "/usr/gopher")
os.ExpandEnv("$NAME lives in ${BURROW}.")
// 清空环境变量
// os.Clearenv()
}
运行结果:
[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
s: [=C:=c:\Users\Mechrevo\Desktop\go_pro ALLUSERSPROFILE=C:\ProgramData APPDATA=C:\Users\Mechrevo\AppData\Roaming APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL=1 CHROME_CRASHPAD_PIPE_NAME=\\.\pipe\crashpad_2748_DLXVXKPMACPMVVXN CommonProgramFiles=C:\Program Files\Common Files CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files CommonProgramW6432=C:\Program Files\Common Files COMPUTERNAME=MORAX ComSpec=C:\WINDOWS\system32\cmd.exe configsetroot=C:\WINDOWS\ConfigSetRoot DriverData=C:\Windows\System32\Drivers\DriverData ELECTRON_RUN_AS_NODE=1 FPS_BROWSER_APP_PROFILE_STRING=Internet Explorer FPS_BROWSER_USER_PROFILE_STRING=Default GOMODCACHE=C:\Users\Mechrevo\go\pkg\mod GOPATH=C:\Users\Mechrevo\go GOPROXY=http://goproxy.cn HOMEDRIVE=C: HOMEPATH=\Users\Mechrevo LOCALAPPDATA=C:\Users\Mechrevo\AppData\Local LOGONSERVER=\\MORAX MySQL=D:\MySQL\mysql-8.0.19-winx64\bin NUMBER_OF_PROCESSORS=12 OneDrive=C:\Users\Mechrevo\OneDrive ORIGINAL_XDG_CURRENT_DESKTOP=undefined OS=Windows_NT Path=C:\Python39\Scripts\;C:\Python39\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NGX;D:\MySQL_5.6.41\mysql-5.6.41-winx64\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\MySQL\mysql-8.0.19-winx64\bin;C:\Go\bin;C:\Program Files\Git\bin;C:\Users\Mechrevo\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Bandizip\;C:\Users\Mechrevo\go\bin;C:\Users\Mechrevo\AppData\Local\Programs\Microsoft VS Code\bin;C:\Program Files (x86)\MyDrivers\DriverGenius;C:\Program Files (x86)\MyDrivers\DriverGenius\ksoft PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW PROCESSOR_ARCHITECTURE=AMD64 PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 158 Stepping 10, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=9e0a ProgramData=C:\ProgramData ProgramFiles=C:\Program Files ProgramFiles(x86)=C:\Program Files (x86) ProgramW6432=C:\Program Files PROMPT=$P$G PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules PUBLIC=C:\Users\Public SDL_AUDIODRIVER=directsound SESSIONNAME=Console SystemDrive=C: SystemRoot=C:\WINDOWS TEMP=C:\Users\Mechrevo\AppData\Local\Temp TMP=C:\Users\Mechrevo\AppData\Local\Temp USERDOMAIN=MORAX USERDOMAIN_ROAMINGPROFILE=MORAX USERNAME=Mechrevo USERPROFILE=C:\Users\Mechrevo VSCODE_AMD_ENTRYPOINT=vs/workbench/api/node/extensionHostProcess VSCODE_CODE_CACHE_PATH=C:\Users\Mechrevo\AppData\Roaming\Code\CachedData\30d9c6cd9483b2cc586687151bcbcd635f373630 VSCODE_CWD=C:\Users\Mechrevo\AppData\Local\Programs\Microsoft VS Code VSCODE_HANDLES_UNCAUGHT_ERRORS=true VSCODE_IPC_HOOK=\\.\pipe\98d9c983e23ef7f29213d28489ea02ed-1.68.1-main-sock VSCODE_IPC_HOOK_EXTHOST=\\.\pipe\vscode-ipc-6c543049-2df1-43e4-bec8-78a0b7d45122-sock VSCODE_LOG_NATIVE=false VSCODE_LOG_STACK=false VSCODE_NLS_CONFIG={"locale":"zh-cn","availableLanguages":{"*":"zh-cn"},"_languagePackId":"bbca1a7059cee8a1b93da8947fee1c4f.zh-cn","_translationsConfigFile":"C:\\Users\\Mechrevo\\AppData\\Roaming\\Code\\clp\\bbca1a7059cee8a1b93da8947fee1c4f.zh-cn\\tcf.json","_cacheRoot":"C:\\Users\\Mechrevo\\AppData\\Roaming\\Code\\clp\\bbca1a7059cee8a1b93da8947fee1c4f.zh-cn","_resolvedLanguagePackCoreLocation":"C:\\Users\\Mechrevo\\AppData\\Roaming\\Code\\clp\\bbca1a7059cee8a1b93da8947fee1c4f.zh-cn\\30d9c6cd9483b2cc586687151bcbcd635f373630","_corruptedFile":"C:\\Users\\Mechrevo\\AppData\\Roaming\\Code\\clp\\bbca1a7059cee8a1b93da8947fee1c4f.zh-cn\\corrupted.info","_languagePackSupport":true} VSCODE_PID=2748 VSCODE_PIPE_LOGGING=true VSCODE_VERBOSE_LOGGING=true windir=C:\WINDOWS ZES_ENABLE_SYSMAN=1]
s2: C:\Users\Mechrevo\go
s2:
--------------
b: false
s3:
[Done] exited with code=0 in 1.169 seconds