目录操作

创建名称为name的目录,权限设置是perm,例如0777

  1. func Mkdir(name string, perm FileMode) error

根据path创建多级子目录,例如test/test1/test2。

  1. func MkdirAll(path string, perm FileMode) error

删除名称为name的目录,当目录下有文件或者其他目录时会出错

  1. func Remove(name string) error

根据path删除多级子目录,如果path是单个名称,那么该目录下的子目录全部删除。

  1. func RemoveAll(path string) error

eg:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. os.Mkdir("test", 0777)
  8. os.MkdirAll("test/test1/test2", 0777)
  9. err := os.Remove("test")
  10. if err != nil {
  11. fmt.Println(err)
  12. }
  13. os.RemoveAll("test")
  14. }

创建文件

根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的。

  1. func Create(name string) (file *File, err Error)

根据文件描述符创建相应的文件,返回一个文件对象

  1. func NewFile(fd uintptr, name string) *File

读取文件

open

该方法打开一个名称为name的文件,但是是只读方式,内部实现其实调用了OpenFile。

  1. func Open(name string) (file *File, err Error)

为了防止文件忘记关闭,我们通常使用defer注册文件关闭语句。eg:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. // 只读方式打开程序同级目录下的word.txt
  8. file, err := os.Open("word.txt")
  9. if err != nil {
  10. fmt.Println( err)
  11. return
  12. }
  13. // 关闭文件
  14. defer file.Close()
  15. }

OpenFile

函数签名如下

  1. func OpenFile(name string, flag int, perm FileMode) (*File, error)

OpenFile函数的第二个参数是文件的打开模式:

  1. const (
  2. // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
  3. O_RDONLY int = syscall.O_RDONLY // 只读模式
  4. O_WRONLY int = syscall.O_WRONLY //只写模式
  5. O_RDWR int = syscall.O_RDWR // 读写混合模式
  6. // The remaining values may be or'ed in to control behavior.
  7. O_APPEND int = syscall.O_APPEND // 写模式的时候将数据附加到文件末尾
  8. O_CREATE int = syscall.O_CREAT // 文件如果不存在就新建
  9. O_EXCL int = syscall.O_EXCL // 和 O_CREATE模式一起使用, 文件必须不存在
  10. O_SYNC int = syscall.O_SYNC //打开文件用于同步 I/O.
  11. O_TRUNC int = syscall.O_TRUNC // 打开文件时清空文件
  12. )

前面三种是文件打开模式,后面五种是打开文件之后相应的操作模式;前面三个你只能选择一个,后面可以多选,中间用”|”隔开。
OpenFile函数的第三个参数perm是文件的权限,跟linux文件权限一致,一个八进制数。r(读)04,w(写)02,x(执行)01。

  1. r ——> 004
  2. w ——> 002
  3. x ——> 001
  1. // Open opens the named file for reading. If successful, methods on
  2. // the returned file can be used for reading; the associated file
  3. // descriptor has mode O_RDONLY.
  4. // If there is an error, it will be of type *PathError.
  5. func Open(name string) (*File, error) {
  6. return OpenFile(name, O_RDONLY, 0)
  7. }
  8. // Create creates or truncates the named file. If the file already exists,
  9. // it is truncated. If the file does not exist, it is created with mode 0666
  10. // (before umask). If successful, methods on the returned File can
  11. // be used for I/O; the associated file descriptor has mode O_RDWR.
  12. // If there is an error, it will be of type *PathError.
  13. func Create(name string) (*File, error) {
  14. return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
  15. }

open 函数和Create 底层都是调用的OpenFile函数

  1. // OpenFile is the generalized open call; most users will use Open
  2. // or Create instead. It opens the named file with specified flag
  3. // (O_RDONLY etc.). If the file does not exist, and the O_CREATE flag
  4. // is passed, it is created with mode perm (before umask). If successful,
  5. // methods on the returned File can be used for I/O.
  6. // If there is an error, it will be of type *PathError.
  7. func OpenFile(name string, flag int, perm FileMode) (*File, error)

Read

读取数据到b中,最大可以读取一个1G 文件

  1. func (file *File) Read(b []byte) (n int, err Error)

eg:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. fileName := "testFile"
  8. currFile,err:=os.Create(fileName)
  9. if err!= nil {
  10. fmt.Println(err,currFile);
  11. }
  12. currFile.WriteString("hello world\n")
  13. currFile.Write([]byte("hello go\n"))
  14. currFile,err = os.Open(fileName);
  15. defer currFile.Close()
  16. buf := make([]byte,1024)
  17. for {
  18. n,_:=currFile.Read(buf)
  19. if 0==n {
  20. break
  21. }
  22. os.Stdout.Write(buf[:n])
  23. }
  24. }

从off开始读取数据到b中

  1. func (file *File) ReadAt(b []byte, off int64) (n int, err Error)

准备测试文件word.txt

  1. 白日依山尽
  2. 黄河入海流
  3. 欲穷千里目
  4. 更上一层楼
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. file, err := os.Open("word.txt")
  8. if err != nil {
  9. fmt.Println(err)
  10. }
  11. defer file.Close()
  12. buf := make([]byte, 1024)
  13. offset := 0
  14. for {
  15. n, err := file.ReadAt(buf, int64(offset))
  16. if len(buf) > 0 {
  17. fmt.Println(string(buf))
  18. }
  19. if err != nil {
  20. fmt.Println(err)
  21. break
  22. }
  23. offset = offset + n
  24. }
  25. }

字节推荐选择2的n次方数数值,不然在中文混合中偏移量就是个坑

bufio.NewReader

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. )
  8. func main() {
  9. file, err := os.Open("word.txt")
  10. if err != nil {
  11. fmt.Println(err)
  12. return
  13. }
  14. defer file.Close()
  15. reader := bufio.NewReader(file)
  16. for {
  17. line, err := reader.ReadString('\n') //按行读取
  18. if err == io.EOF {
  19. fmt.Println("文件读完了")
  20. break
  21. }
  22. if err != nil {
  23. fmt.Println("read file failed, err:", err)
  24. break
  25. }
  26. fmt.Print(line)
  27. }
  28. }

也可以直接调用ReadLine()函数

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. )
  8. func main() {
  9. file, err := os.Open("word.txt")
  10. if err != nil {
  11. fmt.Println(err)
  12. }
  13. defer file.Close()
  14. reader := bufio.NewReader(file)
  15. for {
  16. line, _, err := reader.ReadLine()
  17. if err == io.EOF {
  18. break
  19. }
  20. if err != nil {
  21. fmt.Println(err)
  22. break
  23. }
  24. fmt.Println(string(line))
  25. }
  26. }

ioutil.Readxxx

io/ioutil包的ReadFile方法能够读取完整的文件,只需要将文件名作为参数传入。

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. )
  6. func main() {
  7. content, err := ioutil.ReadFile("word.txt")
  8. if err != nil {
  9. fmt.Println("read file failed, err:", err)
  10. return
  11. }
  12. fmt.Println(string(content))
  13. }

ReadAll 文件输入流

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. )
  7. func main() {
  8. file, err := os.Open("word.txt")
  9. if err != nil {
  10. fmt.Println("read file failed, err:", err)
  11. return
  12. }
  13. defer file.Close()
  14. content, err := ioutil.ReadAll(file)
  15. if err != nil {
  16. fmt.Println("read content failed, err:", err)
  17. return
  18. }
  19. fmt.Println(string(content))
  20. }

文件写入

OpenFile()


os.OpenFile()函数不仅可以指定模式打开文件读文件,也可以指定响应的写模式从而实现文件写入功能。
os.O_RDWR|os.O_CREATE : 文件不存在会新建文件,文件如果存在,会从文件开始处用新内容覆盖原始内容,(如果新内容只有5个字符,原始内容有10个,那么只有开始5个是新内容,后面5个还是以前的内容)
os.O_RDWR|os.O_APPEND : 本次写入的值会在文件末尾进行append操作,不会覆盖以前的内容。
os.O_RDWR|os.O_TRUNC : 打开文件的时候先清空文件。

Writexx

Write

写入byte类型的信息到文件

  1. func (file *File) Write(b []byte) (n int, err Error)

WriteAt

在指定位置开始写入byte类型的信息

  1. func (file *File) WriteAt(b []byte, off int64) (n int, err Error)

WriteString

写入string信息到文件

  1. func (file *File) WriteString(s string) (ret int, err Error)

bufio.NewWriter

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. )
  8. func main() {
  9. file, err := os.OpenFile("word.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
  10. if err != nil {
  11. fmt.Println("open file failed, err:", err)
  12. return
  13. }
  14. defer file.Close()
  15. writer := bufio.NewWriter(file)
  16. for i := 0; i < 10; i++ {
  17. writer.WriteString("hello"+strconv.Itoa(i)+"\n") //将数据先写入缓存
  18. }
  19. writer.Flush() //将缓存中的内容写入文件
  20. }

ioutil.WriteFile

创建文件,如果存在删除 重新写入

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. )
  6. func main() {
  7. str := "hello word"
  8. err := ioutil.WriteFile("word.txt", []byte(str), 0644)
  9. if err != nil {
  10. fmt.Println("write file failed, err:", err)
  11. return
  12. }
  13. }

删除文件

Go语言里面删除文件和删除文件夹是同一个函数, 调用该函数就可以删除文件名为name的文件

  1. func Remove(name string) Error
  1. // Discard 是一个 io.Writer 接口,调用它的 Write 方法将不做任何事情
  2. // 并且始终成功返回。
  3. var Discard io.Writer = devNull(0)
  4. // ReadAll 读取 r 中的所有数据,返回读取的数据和遇到的错误。
  5. // 如果读取成功,则 err 返回 nil,而不是 EOF,因为 ReadAll 定义为读取
  6. // 所有数据,所以不会把 EOF 当做错误处理。
  7. func ReadAll(r io.Reader) ([]byte, error)
  8. // ReadFile 读取文件中的所有数据,返回读取的数据和遇到的错误。
  9. // 如果读取成功,则 err 返回 nil,而不是 EOF
  10. func ReadFile(filename string) ([]byte, error)
  11. // WriteFile 向文件中写入数据,写入前会清空文件。
  12. // 如果文件不存在,则会以指定的权限创建该文件。
  13. // 返回遇到的错误。
  14. func WriteFile(filename string, data []byte, perm os.FileMode) error
  15. // ReadDir 读取指定目录中的所有目录和文件(不包括子目录)。
  16. // 返回读取到的文件信息列表和遇到的错误,列表是经过排序的。
  17. func ReadDir(dirname string) ([]os.FileInfo, error)
  18. // NopCloser 将 r 包装为一个 ReadCloser 类型,但 Close 方法不做任何事情。
  19. func NopCloser(r io.Reader) io.ReadCloser
  20. // TempFile 在 dir 目录中创建一个以 prefix 为前缀的临时文件,并将其以读
  21. // 写模式打开。返回创建的文件对象和遇到的错误。
  22. // 如果 dir 为空,则在默认的临时目录中创建文件(参见 os.TempDir),多次
  23. // 调用会创建不同的临时文件,调用者可以通过 f.Name() 获取文件的完整路径。
  24. // 调用本函数所创建的临时文件,应该由调用者自己删除。
  25. func TempFile(dir, prefix string) (f *os.File, err error)
  26. // TempDir 功能同 TempFile,只不过创建的是目录,返回目录的完整路径。
  27. func TempDir(dir, prefix string) (name string, err error)

文件压缩

  1. package main
  2. import (
  3. "archive/zip"
  4. "fmt"
  5. "io"
  6. "log"
  7. "os"
  8. )
  9. type file struct {
  10. Name, Body string
  11. }
  12. func main() {
  13. // List of Files to Zip
  14. var files = []file{
  15. {"readme.txt", "This archive contains some text files."},
  16. {"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
  17. {"todo.txt", "Get animal handling licence.\nWrite more examples."},
  18. }
  19. for _, file := range files {
  20. f, err := os.Create(file.Name)
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. _, err = f.Write([]byte(file.Body))
  25. if err != nil {
  26. log.Fatal(err)
  27. }
  28. }
  29. output := "dome.zip"
  30. if err := ZipFiles(output, files); err != nil {
  31. panic(err)
  32. }
  33. fmt.Println("Zipped File:", output)
  34. }
  35. // ZipFiles compresses one or many files into a single zip archive file.
  36. // Param 1: filename is the output zip file's name.
  37. // Param 2: files is a list of files to add to the zip.
  38. func ZipFiles(filename string, files []file) error {
  39. newZipFile, err := os.Create(filename)
  40. if err != nil {
  41. return err
  42. }
  43. defer newZipFile.Close()
  44. zipWriter := zip.NewWriter(newZipFile)
  45. defer zipWriter.Close()
  46. // Add files to zip
  47. for _, file := range files {
  48. if err = AddFileToZip(zipWriter, file.Name); err != nil {
  49. return err
  50. }
  51. }
  52. return nil
  53. }
  54. func AddFileToZip(zipWriter *zip.Writer, filename string) error {
  55. fileToZip, err := os.Open(filename)
  56. if err != nil {
  57. return err
  58. }
  59. defer fileToZip.Close()
  60. // Get the file information
  61. info, err := fileToZip.Stat()
  62. if err != nil {
  63. return err
  64. }
  65. header, err := zip.FileInfoHeader(info)
  66. if err != nil {
  67. return err
  68. }
  69. // Using FileInfoHeader() above only uses the basename of the file. If we want
  70. // to preserve the folder structure we can overwrite this with the full path.
  71. header.Name = filename
  72. // Change to deflate to gain better compression
  73. // see http://golang.org/pkg/archive/zip/#pkg-constants
  74. header.Method = zip.Deflate
  75. writer, err := zipWriter.CreateHeader(header)
  76. if err != nil {
  77. return err
  78. }
  79. _, err = io.Copy(writer, fileToZip)
  80. return err
  81. }