1.文件打开和读取
1.文件定义
- 文件是存储在外部介质上的数据集合
- 文件分类:文本文件和二进制文件
- 文件存取方式:随机存取和顺序存取
2.打开文件
package main
import (
"fmt"
"os"
)
func main() {
// 只读方式打开文件
file, err := os.Open("../io/main.go")
if err != nil {
fmt.Printf("open file err: %v\n", err)
return
}
defer file.Close()
}
3.文件读取
// 定义一个字节类型的切片(引用类型)
var buf[128]byte
n, _ := file.Read(buf[:]) // 将读取到的内容塞到buf中,返回读取到的字节长度和err
fmt.Println("read length: ", n)
fmt.Println("data: ", string(buf[:]))
var content []byte
for {
// 定义一个字节类型的切片(引用类型)
var buf[128]byte
// Read方法类似于python中字典的pop方法,从file中删除每次读取得到的内容,这样下次读取就直接从未读取的部分开始截取
_, err := file.Read(buf[:]) // 将读取到的内容塞到buf中,返回读取到的字节长度和err
if err == io.EOF {
// 文件已读取完成
break
}
if err != nil {
fmt.Println("read file err: ", err)
return
}
// 将每次读取的字节数组追加到content中
content = append(content, buf[:]...)
}
fmt.Println(string(content))
var buf[64]byte
// 跳过前128字节,读取64字节内容
n, _ := file.ReadAt(buf[:], 128)
fmt.Println(n)
fmt.Println(string(buf[:]))
4.使用bufio读取文件
reader := bufio.NewReader(file)
line, err := reader.ReadString('\n')
fmt.Println(line)
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
break
}
if err != nil {
fmt.Println("bufio read failed: ", err)
}
fmt.Print(line)
}
4.使用ioutil读取文件
package main
import (
"fmt"
"io/ioutil"
)
func main() {
content, err := ioutil.ReadFile("../io/main.go")
if err != nil {
fmt.Println("ioutil read file error: ", err)
return
}
fmt.Println(string(content))
}
// 内置方法打开文件
file, err := os.Open("../io/main.go")
if err != nil {
fmt.Printf("open file err: %v\n", err)
return
}
// 使用ioutil从文件对象中直接读取全部内容
content, err := ioutil.ReadAll(file)
if err != nil {
fmt.Println("ioutil read file error: ", err)
return
}
fmt.Println(string(content))
5.读取压缩文件
package main
import (
"compress/gzip"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("./aaaa.txt.gz")
if err != nil {
fmt.Printf("open file err: %v\n", err)
return
}
defer file.Close()
reader, errs := gzip.NewReader(file)
if errs != nil {
fmt.Println("gzip new reader failed: ", errs)
return
}
var content []byte
var buf [128]byte
for {
length, err := reader.Read(buf[:])
if err == io.EOF { // 一定要在 nil 前判断
break
}
if err != nil {
fmt.Println("read file error: ", err)
return
}
content = append(content, buf[:length]...)
}
fmt.Println(string(content[:]))
}
package main
import (
"compress/gzip"
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("./aaaa.txt.gz")
if err != nil {
fmt.Printf("open file err: %v\n", err)
return
}
defer file.Close()
fz, errs := gzip.NewReader(file)
if errs != nil {
fmt.Println("gzip new reader failed: ", errs)
return
}
content, errs := ioutil.ReadAll(fz)
if errs != nil {
fmt.Println("ioutil read file error: ", errs)
return
}
fmt.Println(string(content))
}
2.文件打开和写入
1.os.OpenFile(name, mode, perm)
- name: 文件路径
- mode:打开模式
os.O_WRONLY:只写
os.O_CREATE:创建文件
os.O_RDONLY:只读
os.O_RDWR:读写
os.O_TRUNC:清空
os.O_APPEND:追加
- perm:操做权限
2.文件写入示例
- 1.
file.Write():直接往文件中写入二进制
package main
import (
"fmt"
"os"
)
func main() {
// 文件不存在时创建,存在时清空,以读写方式打开
// 如果不清空,再次打开写入时默认是从最开始写入的
file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)
if err != nil {
fmt.Println("open file error: ", err)
return
}
defer file.Close()
file.Write([]byte("这是一个测试"))
}
- 2.
file.WriteAt():往文件指定位置写入二进制
- 3.
file.WriteString():直接往文件写入字符串
// 使用bufio写入文件
package main
import (
"fmt"
"os"
)
func main() {
// 文件不存在时创建,存在时清空,以读写方式打开
// 如果不清空,再次打开写入时默认是从最开始写入的
file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)
if err != nil {
fmt.Println("open file error: ", err)
return
}
defer file.Close()
//bufio.NewWriterSize()
bfd := bufio.NewWriter(file) // 调用的也是NewWriterSize,默认写入大小是4096
writeData1 := "hello world"
writeData2 := " my name is lucy"
bfd.WriteString(writeData1)
bfd.WriteString(writeData2)
// 清空缓冲区,进行缓冲区内容落到磁盘
bfd.Flush()
}
package main
import (
"fmt"
"io/ioutil"
)
func main() {
str := "hello world"
err := ioutil.WriteFile("./test.txt", []byte(str), 0755)
if err != nil {
fmt.Println("write file err: ", err)
return
}
}
3.文件拷贝
package main
import (
"fmt"
"io"
"os"
)
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
fmt.Println("源文件打开失败:", err)
return
}
defer src.Close()
dst, errs := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
if errs != nil {
fmt.Println("目标文件读取失败:", err)
return
}
defer dst.Close()
return io.Copy(dst, src)
}
func main() {
CopyFile("test2.txt", "test.txt")
fmt.Println("Copy done")
}
4.defer详解
![]()
package main
import "fmt"
func test() int {
x := 5
defer func() {
x += 1
fmt.Println("我被调用了,", x)
}()
fmt.Println("defer 在后面执行")
return x
}
func main() {
fmt.Println(test())
}
/*
defer 在后面执行
我被调用了, 6
5
*/
package main
import "fmt"
func test() (x int) {
defer func() {
x += 1
fmt.Println("我被调用了,", x)
}()
fmt.Println("defer 在后面执行")
return 5
}
func main() {
fmt.Println(test())
}
/*
defer 在后面执行
我被调用了, 6
6
*/
5.Go语言路径
- 1.直接使用goland运行程序,则当前路径是src
- 2.命令行运行程序,当前路径就是运行程序文件所在的路径
- 3.运行
go install命令打包后的.exe,当前路径就是bin
6.实现tree命令
package main
import (
"fmt"
"github.com/urfave/cli"
"io/ioutil"
"os"
"path/filepath"
)
/*
|---files 最顶层:fmt.Printf("!---%s\n", filepath.Base(path))
| |----xxx.xx 文件:fmt.Printf("|") fmt.Printf(" |") fmt.Printf("----%s\n", fi.Name())
| | |----xxx 文件夹:if fi.IsDir() fmt.Printf("|") for i:=0;i < deep; i++{fmt.Printf(" |")} fmt.Printf("----%s\n", fi.Name())
go run tree.go ..\..\dcpuffer
*/
func ListDir(path string, deep int) (err error) {
dir, err := ioutil.ReadDir(path) // 获取路径下的所有文件和文件夹
if err != nil {
return err
}
if deep == 1{
// filepath.Base(path) 例如:F:\project\golearn\src\dcpuffer\files ---> files
// 1.如果deep为1,先打印出 |---files
fmt.Printf("!---%s\n", filepath.Base(path))
}
// os.PathSeparator:windows目录分割符是 \
// os.PathSeparator:linux的目录分隔符是 /
sep := string(os.PathSeparator)
for _, fi := range dir {
// 如果fi是目录,继续调用ListDir进行遍历
if fi.IsDir() { // 2.如果是目录,则输出|
fmt.Printf("|")
for i := 0; i < deep; i++{
fmt.Printf(" |")
}
fmt.Printf("----%s\n", fi.Name())
ListDir(path+sep+fi.Name(), deep+1)
continue
}
fmt.Printf("|")
for i := 0; i < deep; i++ {
fmt.Printf(" |")
}
fmt.Printf("----%s\n", fi.Name())
}
return nil
}
func main() {
app := cli.NewApp()
app.Name = "tree"
app.Usage = "list all files"
app.Action = func(c *cli.Context) error {
dir := "." // 如果用户未传递路径,则使用当前路径作为目标
if c.NArg() > 0 {
dir = c.Args()[0]
}
ListDir(dir, 1)
return nil
}
app.Run(os.Args)
}