读取文件内容

os.Open读取文件

读取内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func main() {
// 打开`/etc/passwd`文件
f, err := os.Open("/etc/passwd")
if err != nil {
fmt.Println("Open File Failed:", err)
return
}
defer f.Close()

// 定义一个字节切片
buf := make([]byte, 1024)
// 从文件将读出内容保存到buf字节切片中
n, err := f.Read(buf)
if err != nil {
fmt.Println("Read file Failed:", err)
return
}

// 打印读出的文件内容
fmt.Println(n, err, string(buf[:n]))
}

读取一个完整的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
f, err := os.Open("/etc/passwd")
if err != nil {
return
}
defer f.Close()
buf := make([]byte, 1024)

for {
n, err := f.Read(buf)
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
}
}

os.Create创建文件后写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
testSring := "我爱Golang"
s1 := []byte(testSring)
f, err := os.Create("test.txt")
if err != nil {
fmt.Println("create file filed", err)
return
}
defer f.Close()

// 直接写入
f.Write([]byte("123456\n"))
f.Write(s1)
}

os.OpenFile读取文本文件

语法

1
// OpenFile用法:os.OpenFile(文件名,打开方式,打开模式)

打开方式选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const (
//只读模式
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
//只写模式
O_WRONLY int = syscall.O_WRONLY // open the file write-only.
//可读可写
O_RDWR int = syscall.O_RDWR // open the file read-write.
//追加内容
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
//创建文件,如果文件不存在
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
//与创建文件一同使用,文件必须存在
O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist
//打开一个同步的文件流
O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
//如果可能,打开时缩短文件
O_TRUNC int = syscall.O_TRUNC // if possible, truncate file when opened.
)

打开模式的选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const (
ModeDir FileMode = 1 << (32 - 1 - iota) // d: is a directory 文件夹模式
ModeAppend // a: append-only 追加模式
ModeExclusive // l: exclusive use 单独使用
ModeTemporary // T: temporary file (not backed up) 临时文件
ModeSymlink // L: symbolic link 象征性的关联
ModeDevice // D: device file 设备文件
ModeNamedPipe // p: named pipe (FIFO) 命名管道
ModeSocket // S: Unix domain socket Unix 主机 socket
ModeSetuid // u: setuid 设置uid
ModeSetgid // g: setgid 设置gid
ModeCharDevice // c: Unix character device, when ModeDevice is set Unix 字符设备,当设备模式是设置Unix
ModeSticky // t: sticky 粘性的
// Mask for the type bits. For regular files, none will be set. bit位遮盖.不变的文件设置为none
ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
ModePerm FileMode = 0777 // Unix permission bits 权限位.
)

示例

1
2
3
4
5
6
7
8
9
10
11
func main() {
// 如果文件不存在就创建、以读写方式打开、追加、权限
f,err := os.OpenFile("test.txt",O_CREATE|os.O_WRONLY|os.O_APPEND,0600)
if err != nil{
fmt.Println("open file filed",err)
return
}
defer f.Close()

f.Write([]byte("测试写入\n"))
}

读写数组到文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 写数组
user := []string{
"m1",
"m2",
"m3",
}
f, _ := os.Create("./data.txt")
b, _ := json.Marshal(user)
f.Write(b)
defer f.Close()

//读数组
var arr []string

b, _ := ioutil.ReadFile("./data.txt")
json.Unmarshal(b, &arr)
fmt.Printf("%T",arr)

读写对象到文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//写对象
type user struct {
Name string `json:"name"`
Age int `json:"age"`
}
u1 := user{
Name: "m1",
Age: 22,
}
f, _ := os.Create("./data.txt")
b, _ := json.Marshal(u1)
f.Write(b)
defer f.Close()

//读对象
var obj user

b, _ := ioutil.ReadFile("./data.txt")
json.Unmarshal(b, &obj)
fmt.Printf("%T,%v", obj, obj)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//写[obj,]
type user struct {
Name string `json:"name"`
Age int `json:"age"`
}

m:= []user{
{"m1",1},
{"m2",2},
}

f, _ := os.Create("./data.txt")
b, _ := json.Marshal(m)
f.Write(b)
defer f.Close()

//读[obj,]

var arr []user

b, _ := ioutil.ReadFile("./data.txt") //会自动帮你初始化arr
json.Unmarshal(b, &arr)
fmt.Printf("%T,%v", arr, arr)

输出日志到文件

1
2
3
4
5
6
7
8
9
func main() {
f,err := os.OpenFile("log.out",os.O_CREATE|os.O_APPEND|os.O_RDWR,0700)
if err!= nil{
return
}
defer f.Close()
log.SetOutput(f)
log.Println("test log") // 打印的日志写入到Log.out文件中
}

计算文件md5小工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
func main() {
var name string
flag.StringVar(&name,"p","","path")
flag.Parse()

if name == ""{
return
}

f,err := os.Open(name)
defer f.Close()
if err != nil{
fmt.Println("文件打开失败",err)
return
}

hasher := md5.New()
ctx := make([]byte,1024)
for {
n,err := f.Read(ctx)
if err == io.EOF {
break
}
hasher.Write(ctx[:n])
}
fmt.Printf("%x",hasher.Sum(nil))
}

运行示例

1
2
3
4
5
6
7
// 小工具计算结果
$ go run fileio.go -p fileio.go
12af4076365a97ae5123f02e6133e3f5

// mac自带工具计算结果
$ md5 fileio.go
MD5 (fileio.go) = 12af4076365a97ae5123f02e6133e3f5

文件操作

判断文件是否存在

golang通过使用 os包中的Stat()函数和IsNotExist()函数即可判断文件或文件夹是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func FileIsExists(path string) bool {
_,err := os.Stat(path)
if err == nil {
return true
}else if os.IsNotExist(err){
return false
}else {
panic(err)
}
}

func main() {
fmt.Println(FileIsExists("/etc/passwd")) // 判断/etc/passwd文件是否存在 返回true
}

文件属性查看

1
2
3
4
5
6
7
8
9
10
func main() {
fileInfo,err := os.Stat("/etc/passwd")
fmt.Println(err)

fmt.Println(fileInfo.Name()) // 打印文件的名称
fmt.Println(fileInfo.Size()) // 打印文件的字节大小
fmt.Println(fileInfo.Mode()) // 打印文件的权限
fmt.Println(fileInfo.ModTime()) // 打印文件的最后修改时间
fmt.Println(fileInfo.IsDir()) // 判断是否是一个目录
}

对文件操作

对文件改名、删除、修改权限、

1
2
3
4
5
6
7
8
func main() {
os.Rename("log.out","log.txt") // 将文件log.out改名成log.txt
os.Remove("log.txt") // 将Log.txt文件删除
os.Chmod("log.txt",077) // 为log.txt设置权限掩码
os.Chown("log.txt",1,1) // 为log.txt设置属主和属组
os.Chtimes("log.txt",time.Now(),time.Now()) // 修改文件的修改时间
os.Link() // 创建超链接
}

目录操作

创建和删除目录

1
2
3
4
5
6
7
func main() {
os.Mkdir("test",os.ModePerm) // 创建单个目录
fmt.Println(os.MkdirAll("test/a/b",os.ModePerm)) // 递归创建目录

fmt.Println(os.Remove("test/a/b")) // 移除单个目录,注意只能移除空目录,当此目录下有文件或目录时会报错
os.RemoveAll("test") // 移除所有目录
}

获取目录下文件或目录

1
2
3
4
5
6
7
8
9
10
11
func main() {
// 获取指定/tmp目录下文件和目录
f,err := os.Open("/tmp/")
if err!=nil {
return
}
defer f.Close()

files,err := f.Readdirnames(-1)
fmt.Println(files)
}

递归获取目录下所有文件和目录

获取指定目录下的所有目录和文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func getDir(path string) {
f, err := os.Open(path)
if err != nil {
return
}
defer f.Close()

names, err := f.Readdirnames(-1)
if err != nil {
return
}
for _, name := range names {
fpath := path + "/" + name
if fileInfo, err := os.Stat(fpath); err == nil {
if fileInfo.IsDir() {
fmt.Println("dir:", fpath)
getDir(fpath)
}
fmt.Println("files:", fpath)
}
}
}

func main() {
getDir("/tmp") // 获取/tmp目录下的所有文件和目录
}