golang中的文件操作

2020-11-03 14:35:52 浏览数 (1)

与Java类似,也是通过流的形式读取文件,将文件读入内存使用输入流,将内存中数据写入文件使用输出流。

File结构体

os.File表示一个打开的文件对象

打开文件 os.Open()

代码语言:javascript复制
func Open(name string) (file *File, err error)

Open打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有O_RDONLY模式。如果出错,错误底层类型是*PathError。

关闭文件 close()

读文件

带缓存的读
代码语言:javascript复制
func (f *File) Close() error
代码语言:javascript复制
func main() {
    file, err := os.Open("e:/record.txt")
    if err != nil {
        fmt.Println("ERROR: ", err)
    }
    defer file.Close()
    // 带有缓存的读 默认大小4096byte
    reader := bufio.NewReader(file)
    for {
        // 每次只往str读到一个换行就结束
        str, err := reader.ReadString('n')
        fmt.Print(str)
        // io.EOF 表示读到文件末尾了
        if err == io.EOF {
            break
        }
    }
    fmt.Println("n文件读取结束")
}
一次性读

io/ioutil 的readFile方法可以一次性将整个文件读入内存,不适合大文件的读取。

代码语言:javascript复制
func ReadFile(filename string) ([]byte, error)

该方法将文件的打开关闭封装到方法内部了。

代码语言:javascript复制
func main() {
    data, err := ioutil.ReadFile("e:/record.txt")
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(string(data))
    }
}

写文件

os包下的openFile函数

代码语言:javascript复制
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

name : 文件名
flag : 文件打开模式 取值如下:
const (
    O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
    O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
    O_RDWR   int = syscall.O_RDWR   // 读写模式打开文件
    O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
    O_CREATE int = syscall.O_CREAT  // 如果不存在将创建一个新文件
    O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用,文件必须不存在
    O_SYNC   int = syscall.O_SYNC   // 打开文件用于同步I/O
    O_TRUNC  int = syscall.O_TRUNC  // 如果可能,打开时清空文件
)
上述模式可以组合使用
perm : 文件模式 用于权限控制 Unix中的rwx rwx rwx windows下无效

使用带缓存的写时是先写到缓存当中的,当满了时才落到磁盘上,因此写完后需要flash将此时缓存中剩余的写入磁盘。

代码语言:javascript复制
func main() {
    // 只写 和 创建配合使用
    file, err := os.OpenFile("e:/abc.txt", os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()
    // 使用带缓存的写 默认亦是4096byte
    writer := bufio.NewWriter(file)
    for i := 0; i < 1024; i   {
        writer.WriteString("hello golang n")
    }
    // 如果不flush可能会使的缓存区剩余的部分不能写入磁盘
    writer.Flush()
}

文件拷贝

一次性读/写拷贝

代码语言:javascript复制
func main() {
    data, err := ioutil.ReadFile("e:/abc.txt")
    if err != nil {
        fmt.Println(err)
    }
    err1 := ioutil.WriteFile("e:/abcd.txt", data, 0666)
    if err1 != nil {
        fmt.Println(err1)
    }
}

buffer读写拷贝

代码语言:javascript复制
func main() {
    file1, err1 := os.OpenFile("e:/abc.txt", os.O_RDONLY, 0666)
    file2, err2 := os.OpenFile("e:/abcd.txt", os.O_WRONLY|os.O_CREATE, 0666)
    defer file1.Close()
    defer file2.Close()
    if err1 != nil {
        fmt.Println(err1)
    }
    if err2 != nil {
        fmt.Println(err2)
    }
    reader := bufio.NewReader(file1)
    writer := bufio.NewWriter(file2)
    for {
        data, err := reader.ReadString('n')
        writer.WriteString(data)
        if err == io.EOF {
            break
        }
    }
    writer.Flush()

}

使用io.Copy方法复制

代码语言:javascript复制
func Copy(dst Writer, src Reader) (written int64, err error) {
    return copyBuffer(dst, src, nil)
}

将输入src复制到dst上,尤其需要注意的是,当使用bufio创建的writer时,copy()执行完后需要手动flash().

代码语言:javascript复制
func main() {
    file1, err1 := os.Open("e:/aaa.jpg")
    file2, err2 := os.OpenFile("e:/bbb.jpg", os.O_WRONLY|os.O_CREATE, 0666)
    defer file1.Close()
    defer file2.Close()
    if err1 != nil {
        fmt.Println(err1)
    }
    if err2 != nil {
        fmt.Println(err2)
    }
    reader := bufio.NewReader(file1)
    writer := bufio.NewWriter(file2)
    wirten, err := io.Copy(writer, reader)
    writer.Flush()
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(wirten)
    }
}

0 人点赞