部分内容摘自博客

读取文件

一次性读取一个文件的所有内容–ReadFile

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    //func ReadFile(filename string) ([]byte, error)
    data, err := ioutil.ReadFile("./connect.go")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(string(data))
    }
}

分多次读,每次读取指定长度内容–Read

package main

import (
    "fmt"
    "os"
)

func main() {
    //func Open(name string) (*File, error)
    f, err := os.Open("./connect.go")
    defer f.Close() //注意要关闭文件
    if err != nil {
        panic(err)
    } else {
        buffer := make([]byte, 20)
        //func (f *File) Read(b []byte) (n int, err error)
        //使用Read方法,将文件内容读入buffer切片中
        length, err := f.Read(buffer)
        if err != nil {
            panic(err)
        } else {
            fmt.Println("读取了", length, "字节内容")
            fmt.Println(string(buffer))
        }

        //第二次读取,会接着上一次的位置继续读
        length, err = f.Read(buffer)
        if err != nil {
            panic(err)
        } else {
            fmt.Println("读取了", length, "字节内容")
            fmt.Println(string(buffer))
        }
    }
}

使用os的Read时,

  • 1、如果文件的内容长度大于buffer切片的长度,那么,只会读取文件buffer切片长度的内容,返回的长度就是切片的长度。

  • 2、如果文件内容小于切片的长度,那么会读出文件的所有内容,返回的长度就是读入buffer的实际长度。

  • 3、如果执行多次从文件中读取,那么后面一次读取都会在前面一次读取结束的位置那里接着继续读。

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

设置游标

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

f.Seek(3, 1)
0表示相对于文件的原点,从文件的开头往后offset个字符的位置处开始读。

  • 1 表示相对于当前偏移量,即已经读过至少一次了,游标此时不在文件原点,而在其他地方,从那个地方往后offset字符的位置处开始读。

  • 2 表示相对于末尾,将文件的末尾作为原点,offset一般为负数,表示从文件末尾往前数offset个字符开始读。

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

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

f, err := os.Open("connect.go")
defer f.Close()
if err != nil {
    panic(err)
}
//func NewReader(rd io.Reader) *Reader
reader := bufio.NewReader(f)

totLine := 0

for {
    //func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error)
    content, isPrefix, err := reader.ReadLine()

    fmt.Println(string(content), isPrefix, err)

    //当单行的内容超过缓冲区时,isPrefix会被置为真;否则为false;
    if !isPrefix {
        totLine++
    }

    if err == io.EOF {
        fmt.Println("一共有", totLine, "行内容")
        break
    }
}

创建文件和获取文件信息

创建文件–Create

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

获取文件的信息–Stat

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

写入文件

写入内容+读取文件–WriteFile

// 写入文件
path := "./demo.txt"
content := "准备写入的内容"
//func WriteFile(filename string, data []byte, perm os.FileMode) error
err := ioutil.WriteFile(path, []byte(content), 0666)

if err != nil {
    panic(err)
}

//读取内容
data, err := ioutil.ReadFile(path)
if err != nil {
    panic(err)
}
fmt.Println(string(data))

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

path := "test.txt"
f, err := os.Create(path)
defer f.Close()
if err != nil {
    panic(err)
}
//func (f *File) WriteAt(b []byte, off int64) (n int, err error)
length, err := f.WriteAt([]byte("abcdefgh"), 0)
if err != nil {
    panic(err)
}
fmt.Println(length) //8
//abcdefgh

//第二次写入
length, err = f.WriteAt([]byte("xyz"), 3)
if err != nil {
    panic(err)
}
fmt.Println(length) //3
//abcxyzgh

通过buffer writer来写入文件内容

path := "test.txt"
f, err := os.Create(path)
defer f.Close()
if err != nil {
    panic(err)
}
//func NewWriter(w io.Writer) *Writer
bufferWrite := bufio.NewWriter(f)
if err != nil {
    panic(err)
}

demo := "1234567890"
for _, v := range demo {
    //将数据写入缓冲区
    //func (b *Writer) WriteString(s string) (int, error)
    bufferWrite.WriteString(string(v))
}
data, _ := ioutil.ReadFile(path)
fmt.Println(string(data))   //空的内容

//将缓冲区的数据写入文件
//func (b *Writer) Flush() error
bufferWrite.Flush()

data, _ = ioutil.ReadFile(path)
fmt.Println(string(data))   //1234567890

将字符串写入文件

// 使用 create 创建一个名字为 test.txt 的文件。如果这个文件已经存在,那么 create 函数将截断这个文件。该函数返回一个文件描述符。f, err := os.Create("test.txt")

// 使用 WriteString 将字符串 Hello World 写入到文件里面。这个方法将返回相应写入的字节数,如果有错误则返回错误。
l, err := f.WriteString("Hello World")

import (
    "fmt"
    "os"
)

func main() {
    // 使用 create 创建一个名字为 test.txt 的文件。如果这个文件已经存在,那么 create 函数将截断这个文件。该函数返回一个文件描述符。
    f, err := os.Create("test.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    // 使用 WriteString 将字符串 Hello World 写入到文件里面。这个方法将返回相应写入的字节数,如果有错误则返回错误。
    l, err := f.WriteString("Hello World")
    if err != nil {
        fmt.Println(err)
        f.Close()
        return
    }
    fmt.Println(l, "bytes written successfully")
    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
}

字节写入文件

可以写入图片之类

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.Create("./bytes")
    if err != nil {
        fmt.Println(err)
        return
    }
    d2 := []byte{104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100}
    n2, err := f.Write(d2)
    if err != nil {
        fmt.Println(err)
        f.Close()
        return
    }
    fmt.Println(n2, "bytes written successfully")
    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
}

将字符串一行一行的写入文件

// WriteFile 写文件
func WriteFile(lines []string) {
    f, err := os.Create("afile.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    for _, line := range lines {
        _, err := f.WriteString(line + "\n")
        if err != nil {
            log.Fatal(err)
        }
    }
}
func Write(d []string) {
    f, err := os.Create("lines")
    if handleErr(err){
        f.Close()
        return 
    }

    for _, v := range d {
        // 用迭代并使用 for rang 循环这个数组,并使用 Fprintln Fprintln 函数 将 io.writer 做为参数,并且添加一个新的行,
        fmt.Fprintln(f, v)
        if handleErr(err){
            return 
        }
    }
    err = f.Close()
    if handleErr(err){
        return 
    }
    fmt.Println("file written successfully")
}
func handleErr(err error)bool{
    if err != nil {
        fmt.Println(err)
        return true
    }
    return false
}

追加写入文件

import (
    "fmt"
    "os"
)

func main() {
    f, err := os.OpenFile("lines", os.O_APPEND|os.O_WRONLY, 0644)
    if err != nil {
        fmt.Println(err)
        return
    }
    newLine := "File handling is easy."
    _, err = fmt.Fprintln(f, newLine)
    if err != nil {
        fmt.Println(err)
                f.Close()
        return
    }
    err = f.Close()
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("file appended successfully")
}

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

func ReadFile(filename string) {
    f, err := os.Open(filename)
    defer f.Close() //注意要关闭文件
    if err != nil {
        panic(err)
    } else {
        buffer := make([]byte, 20)
        //循环读取
        for {
            length, err := f.Read(buffer)
            //如果错误信息是其他类型的,则直接panic
            if err != nil && err != io.EOF {
                panic(err)
            }

            //fmt.Println("读取了", length, "字节内容")
            if length == 20 {
                fmt.Print(string(buffer))
            } else {
                fmt.Print(string(buffer[0:]))
            }

            //注意,错误信息是以io包的EOF时,表示读取到文件末尾
            if err == io.EOF {
                fmt.Println("读取完毕")
                break
            }
        }
    }
}
分类: go

浙公网安备33011302000604

辽ICP备20003309号