go标准库之文件操作

go标准库中的文件操作有os包,io包,bufio包和ioutil包,可以做以下区分:

  • 目录操作以及文件名相关的操作使用os包
  • 文件内容操作建议优先使用ioutil包,然后是bufio包,然后是io包

    一、目录操作

    1、创建目录
    (1)os.Mkdir:创建单个目录(要求上级目录必须存在)
  • 使用说明:os.Mkdir(dirname string, perm fileMode)
  • 参数说明:
    • dirname为要创建的目录名
    • perm为文件的模式和权限(使用os中的定义的常量os.ModeDir,os.ModeType,os.ModePerm等)

实例:

  1. err := os.Mkdir("data/www/test/java", os.ModePerm)
  2. if err != nil {
  3. if os.IsExist(err) {
  4. fmt.Println("目录已存在")
  5. return
  6. }
  7. fmt.Printf("create dir failed:%s ", err)
  8. return
  9. }

注:这里的os.ModePerm表示目录的权限

(2)os.MkdirAll:递归创建目录

与os.Mkdir用法一样,是不过它可以递归的创建目录,如果当前创建的目录的上一级目录不存在,它也会创建

2、修改目录权限

os.Chmod:修改目录权限(类似于shell中的chmod)

  • 使用说明:os.Chmod(dirname string, mode FileMode)
  • 参数说明:
    • dirname为目录或文件名
    • mode为权限

实例:

  1. const DIR = "data/www"
  2. stats, err := os.Stat(DIR)
  3. if err != nil {
  4. fmt.Printf("get stat of %s failed:%s ", DIR, err)
  5. return
  6. }
  7. fmt.Println(stats.Mode())
  8. os.Chmod(DIR, 0644)
  9. stats, err = os.Stat(DIR)
  10. if err != nil {
  11. fmt.Printf("get stat of %s failed:%s ", DIR, err)
  12. return
  13. }
  14. fmt.Println(stats.Mode())
3、获取当前目录

使用说明:os.Getwd()
实例:

  1. curDir, err := os.Getwd()
  2. if err != nil {
  3. fmt.Printf("get working directory failed,:%s ", err)
  4. return
  5. }
  6. fmt.Println(curDir)
4、切换目录
  • 使用说明:os.Chdir(newDir string)
  • 参数说明:
    • newDir为切换后的目录名

实例:

  1. curDir, err := os.Getwd()
  2. if err != nil {
  3. fmt.Printf("get working directory failed,:%s ", err)
  4. return
  5. }
  6. fmt.Printf("current directory is:%s ", curDir)
  7. os.Chdir("data")
  8. nowDir, err := os.Getwd()
  9. if err != nil {
  10. fmt.Printf("get working directory failed,:%s ", err)
  11. return
  12. }
  13. fmt.Printf("current directory is:%s ", nowDir)
5、删除目录(文件)
(1)os.Remove(dirName string)
  • 功能说明:删除非空目录
  • 参数说明:dirName为要删除的目录
    ·
    实例:
  1. err := os.Remove("data/www/test/java")
  2. if err != nil {
  3. fmt.Printf("remove directory failed:%s ", err)
  4. }
(2)os.RemoveAll(dirName string)

它与os.Remove用法是一样的,只不过它可以递归的删除目录,如果目录是非空的,也同时删除目录下的目录和文件

6、获取目录或文件状态信息

os.Stat

  • 功能说明:获取目录或文件的状态信息
  • 用法:os.Stat(filename string)
  • 参数说明:
    • filename为目标目录或文件

实例:

  1. fileInfo, err := os.Stat("data/www/test/java/hello.txt")
  2. if err != nil {
  3. fmt.Printf("get file info failed:%s", err)
  4. return
  5. }
  6. fmt.Printf("name:%s ", fileInfo.Name())
  7. fmt.Printf("size:%d ", fileInfo.Size())
  8. fmt.Printf("mode:%s ", fileInfo.Mode())
  9. fmt.Printf("modTime:%s ", fileInfo.ModTime())
  10. fmt.Println(fileInfo.IsDir())
  11. fmt.Println(fileInfo.Sys())
7、读取目录
(1)通过os包的Readdir或Readdirnames

file.Readdir

  • 功能说明:
  • 用法:file.Readdir(n int)
  • 参数说明:
    • n为子目录或文件数(如果<0表示读取所有)

实例:

  1. fd, err := os.Open("data/www")
  2. if err != nil {
  3. fmt.Printf("open directory failed:%s", err)
  4. return
  5. }
  6. defer fd.Close()
  7. //fileInfo为结构fileinfo
  8. fileInfo, err := fd.Readdir(-1)
  9. if err != nil {
  10. fmt.Printf("read dir failed:%s ", err)
  11. return
  12. }
  13. for _, v := range fileInfo {
  14. fmt.Println(v.Name())
  15. }

file.Readdirnames,功能与Readdir类似,只不过它返回的是一个包含子目录或文件的一个列表
例如:

  1. fd, err := os.Open("data/www")
  2. if err != nil {
  3. fmt.Printf("open directory failed:%s", err)
  4. return
  5. }
  6. defer fd.Close()
  7. fileInfo, err := fd.Readdirnames(-1)
  8. if err != nil {
  9. fmt.Printf("read dir failed:%s ", err)
  10. return
  11. }
  12. for _, v := range fileInfo {
  13. fmt.Println(v)
  14. }
(2)通过ioutil包

ioutil.Readdir

  • 功能说明:与file.Readdir一样,读取目录,返回目录子目录或文件状态信息
  • 用法说明:ioutil.Readdir(dirname string)
  • 参数说明:
    • dirname为目录名

实例:

  1. fileInfo, err := ioutil.ReadDir("data/www")
  2. if err != nil {
  3. fmt.Printf("read dir failed:%s ", err)
  4. return
  5. }
  6. for _, v := range fileInfo {
  7. fmt.Println(v.Name())
  8. }

二、针对文件名的操作

1、创建文件
  • 功能说明:创建一个文件,并打开它
  • 使用说明:os.Create(filename string)
  • 参数说明:
    • filename为创建的文件名

实例:

  1. fd, err := os.Create("data/www/test/java/test.txt")
  2. defer fd.Close()
  3. if err != nil {
  4. fmt.Printf("create file failed:%s", err)
  5. }
  6. fmt.Println("create file success")

返回值说明:
fd 为文件描述符
err为错误信息

2、文件重命名
  • 功能说明:重命名文件,也可以认为是剪切文件(类似shell中的mv)
  • 使用说明:os.Rename(oldName string, newName string)
  • 参数说明:
    • oldName为旧的文件名
    • newName为新的文件名
      实例:
      1. err := os.Rename("data/www/test/java/test.txt", "data/www/test/java/hello.txt")
      2. if err != nil {
      3. fmt.Printf("rename file failed:%s ", err)
      4. }

三、针对文件内容的操作

1、读取文件内容
(1)通过os包读取

通过os.Open和file.Read来读取

  1. func ReadByOs(filename string) {
  2. start := time.Now()
  3. //打开文件
  4. fd, err := os.Open(filename)
  5. if err != nil {
  6. fmt.Printf("open file failed:%s ", err)
  7. }
  8. defer fd.Close()
  9. //保存临时内容的缓存区
  10. buf := make([]byte, 1024)
  11. //保存读取内容的缓存区
  12. chunks := make([]byte, 1024, 1024)
  13. for {
  14. //分片读取文件内容
  15. count, err := fd.Read(buf)
  16. if err != nil && err != io.EOF {
  17. fmt.Printf("read file failed:%s ", err)
  18. return
  19. }
  20. //读取的内容为0个
  21. if count == 0 {
  22. break
  23. }
  24. //将分片内容存入完整的缓存区中
  25. chunks = append(chunks, buf[:count]...)
  26. }
  27. end := time.Now()
  28. fmt.Println(string(chunks))
  29. fmt.Println(end.Sub(start))
  30. }
(2)通过bufio包读取

通过os.Open和bufio.NewReader和reader.Read来读取

  1. func ReadByBufio(filename string) {
  2. start := time.Now()
  3. fd, err := os.Open(filename)
  4. if err != nil {
  5. fmt.Printf("open file failed:%s ", err)
  6. }
  7. defer fd.Close()
  8. reader := bufio.NewReader(fd)
  9. buf := make([]byte, 1024)
  10. chunks := make([]byte, 1024, 1024)
  11. for {
  12. count, err := reader.Read(buf)
  13. if err != nil && err != io.EOF {
  14. fmt.Printf("read file failed:%s ", err)
  15. return
  16. }
  17. if count == 0 {
  18. break
  19. }
  20. chunks = append(chunks, buf[:count]...)
  21. }
  22. end := time.Now()
  23. fmt.Println(string(chunks))
  24. fmt.Println(end.Sub(start))
  25. }
(3)通过io/ioutil包读取

通过ioutil.ReadFile来读取

  1. func ReadByIoutil(filename string) {
  2. start := time.Now()
  3. data, err := ioutil.ReadFile(filename)
  4. if err != nil {
  5. fmt.Printf("read file failed:%s ", err)
  6. }
  7. end := time.Now()
  8. fmt.Println(string(data))
  9. fmt.Println(end.Sub(start))
  10. }
2、写文件
(1)通过os包和io包来实现写文件
  • 通过os.OpenFile打开文件
  • 通过io.WriteString写入文件内容
  • 通过file.Close关闭文件

实例:

  1. fd, err := os.OpenFile(filename, os.O_RDWR, os.ModePerm)
  2. if err != nil {
  3. fmt.Printf("open file failed:%s ", err)
  4. return
  5. }
  6. defer fd.Close()
  7. n, err := io.WriteString(fd, "writing by file.WriteString")
  8. if err != nil {
  9. fmt.Printf("write file failed:%s ", err)
  10. }
  11. fmt.Printf("共写入%d个字节 ", n)

注:os.OpenFile的第二个参数为打开的标识符O_RDWR表示可读可写的模式

(2)通过os包和bufio包实现
  1. fd, err := os.OpenFile(filename, os.O_RDWR, os.ModePerm)
  2. if err != nil {
  3. fmt.Printf("open file failed:%s ", err)
  4. return
  5. }
  6. defer fd.Close()
  7. writer := bufio.NewWriter(fd)
  8. n, err := writer.WriteString("writing by bufio.writer")
  9. if err != nil {
  10. fmt.Printf("write file failed:%s ", err)
  11. }
  12. writer.Flush()
  13. fmt.Printf("共写入%d个字节 ", n)
(3)通过ioutil包实现
  1. content := "writing by ioutil"
  2. err := ioutil.WriteFile(filename, []byte(content), os.ModePerm)
  3. if err != nil {
  4. fmt.Printf("write file failed:%s ", err)
  5. }