[

](https://www.cnblogs.com/-beyond/p/9203272.html)

利用io/ioutil包一次性读取一个文件的所有内容—ReadFile

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. //func ReadFile(filename string) ([]byte, error)
  8. data, err := os.ReadFile("./connect.go")
  9. if err != nil {
  10. fmt.Println(err)
  11. } else {
  12. fmt.Println(string(data))
  13. }
  14. }

分多次读,每次读取指定长度的文件内容—Read

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. //func Open(name string) (*File, error)
  8. f, err := os.Open("./connect.go")
  9. defer f.Close() //注意要关闭文件
  10. if err != nil {
  11. panic(err)
  12. } else {
  13. buffer := make([]byte, 20)
  14. //func (f *File) Read(b []byte) (n int, err error)
  15. //使用Read方法,将文件内容读入buffer切片中
  16. length, err := f.Read(buffer)
  17. if err != nil {
  18. panic(err)
  19. } else {
  20. fmt.Println("读取了", length, "字节内容")
  21. fmt.Println(string(buffer))
  22. }
  23. //第二次读取,会接着上一次的位置继续读
  24. length, err = f.Read(buffer)
  25. if err != nil {
  26. panic(err)
  27. } else {
  28. fmt.Println("读取了", length, "字节内容")
  29. fmt.Println(string(buffer))
  30. }
  31. }
  32. }

  注意,使用os的Read时,
  1、如果文件的内容长度大于buffer切片的长度,那么,只会读取文件buffer切片长度的内容,返回的长度就是切片的长度。
  2、如果文件内容小于切片的长度,那么会读出文件的所有内容,返回的长度就是读入buffer的实际长度。
  3、如果执行多次从文件中读取,那么后面一次读取都会在前面一次读取结束的位置那里接着继续读。
  4、如果

从指定位置开始读—Seek、ReadAt

  1. //设置游标
  2. //func (f *File) Seek(offset int64, whence int) (ret int64, err error)
  3. length, err := f.Seek(3, 1)

  先说第二个参数,可以使0,1,2:
  0表示相对于文件的原点,从文件的开头往后offset个字符的位置处开始读。
  1 表示相对于当前偏移量,即已经读过至少一次了,游标此时不在文件原点,而在其他地方,从那个地方往后offset字符的位置处开始读。
  2 表示相对于末尾,将文件的末尾作为原点,offset一般为负数,表示从文件末尾往前数offset个字符开始读。

  1. //从文件的起始位置开始的往后offset位置开始读
  2. //func (f *File) ReadAt(b []byte, off int64) (n int, err error)
  3. length, err := f.ReadAt(buffer, 5)

使用os和io包实现io/ioutil包的ReadFile

  1. func ReadFile(filename string) {
  2. f, err := os.Open(filename)
  3. defer f.Close() //注意要关闭文件
  4. if err != nil {
  5. panic(err)
  6. } else {
  7. buffer := make([]byte, 20)
  8. //循环读取
  9. for {
  10. length, err := f.Read(buffer)
  11. //如果错误信息是其他类型的,则直接panic
  12. if err != nil && err != io.EOF {
  13. panic(err)
  14. }
  15. //fmt.Println("读取了", length, "字节内容")
  16. if length == 20 {
  17. fmt.Print(string(buffer))
  18. } else {
  19. fmt.Print(string(buffer[0:]))
  20. }
  21. //注意,错误信息是以io包的EOF时,表示读取到文件末尾
  22. if err == io.EOF {
  23. fmt.Println("读取完毕")
  24. break
  25. }
  26. }
  27. }
  28. }

使用bufio包输出每一行的内容,并统计行数

  1. f, err := os.Open("connect.go")
  2. defer f.Close()
  3. if err != nil {
  4. panic(err)
  5. }
  6. //func NewReader(rd io.Reader) *Reader
  7. reader := bufio.NewReader(f)
  8. totLine := 0
  9. for {
  10. //func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
  11. content, isPrefix, err := reader.ReadLine()
  12. fmt.Println(string(content), isPrefix, err)
  13. //当单行的内容超过缓冲区时,isPrefix会被置为真;否则为false;
  14. if !isPrefix {
  15. totLine++
  16. }
  17. if err == io.EOF {
  18. fmt.Println("一共有", totLine, "行内容")
  19. break
  20. }
  21. }

创建文件—Create

  1. //创建文件
  2. //func Create(name string) (*File, error)
  3. newFile, err := os.Create("demo.txt")
  4. defer newFile.Close()
  5. if err != nil {
  6. panic(err)
  7. }

获取文件的信息—Stat

  1. //获取文件信息
  2. //func Stat(name string) (FileInfo, error)
  3. info, err := os.Stat("test.txt")
  4. if err != nil {
  5. //func IsNotExist(err error) bool
  6. if os.IsNotExist(err) {
  7. panic("文件不存在")
  8. } else {
  9. panic(err) //其实err信息中就能看出来上一个判断是否成立,只是提示有这种判断方法而已
  10. }
  11. }
  12. fmt.Println(info.Name(), info.Size(), info.Mode())

创建并写入内容—WriteFile

  1. path := "./demo.txt"
  2. content := "准备写入的内容"
  3. //func WriteFile(filename string, data []byte, perm os.FileMode) error
  4. err := ioutil.WriteFile(path, []byte(content), 0666)
  5. if err != nil {
  6. panic(err)
  7. }
  8. //读取内容
  9. data, err := ioutil.ReadFile(path)
  10. if err != nil {
  11. panic(err)
  12. }
  13. fmt.Println(string(data))

在文件指定位置出写入内容—WriteAt

  1. path := "test.txt"
  2. f, err := os.Create(path)
  3. defer f.Close()
  4. if err != nil {
  5. panic(err)
  6. }
  7. //func (f *File) WriteAt(b []byte, off int64) (n int, err error)
  8. length, err := f.WriteAt([]byte("abcdefgh"), 0)
  9. if err != nil {
  10. panic(err)
  11. }
  12. fmt.Println(length) //8
  13. //abcdefgh
  14. //第二次写入
  15. length, err = f.WriteAt([]byte("xyz"), 3)
  16. if err != nil {
  17. panic(err)
  18. }
  19. fmt.Println(length) //3
  20. //abcxyzgh

通过buffer writer来写入文件内容

  1. path := "test.txt"
  2. f, err := os.Create(path)
  3. defer f.Close()
  4. if err != nil {
  5. panic(err)
  6. }<br>
  7. //func NewWriter(w io.Writer) *Writer
  8. bufferWrite := bufio.NewWriter(f)
  9. if err != nil {
  10. panic(err)
  11. }
  12. demo := "1234567890"
  13. for _, v := range demo {
  14. //将数据写入缓冲区
  15. //func (b *Writer) WriteString(s string) (int, error)
  16. bufferWrite.WriteString(string(v))
  17. }
  18. data, _ := ioutil.ReadFile(path)
  19. fmt.Println(string(data)) //空的内容
  20. //将缓冲区的数据写入文件
  21. //func (b *Writer) Flush() error
  22. bufferWrite.Flush()
  23. data, _ = ioutil.ReadFile(path)
  24. fmt.Println(string(data)) //1234567890

文献参考 https://www.cnblogs.com/-beyond/p/9203272.html