Go中的文件读写
在 Go 语言中,文件使用指向 os.File 类型的指针来表示的,也叫做文件句柄 。我们来看一下os包的使用方式。
1.读取文件
os包提供了两种打开文件的方法:
Open(name string) (*File, error)
func OpenFile(name string, flag int, perm FileMode) (*File, error)
第一个方法是以只读的方式去打开文件,如果文件不存在或者程序没有足够的权限打开这个文件,Open函数会返回错误;
第二个方法会自由一些,你可以设置打开文件的方式,以及文件的操作权限,后面我们详细说明。
package main
import (
    "fmt"
    "os"
)
func main() {
    file, e := os.Open("c:/1.txt")
    if e != nil {
        fmt.Println(e)
    }
    buf := make([]byte,1024)
    for {
        len, _ := file.Read(buf)
        if len == 0 {
            break
        }
        fmt.Println(string(buf))
    }
    buf1 := make([]byte,1024)
    offset := 0
    for {
        len1, _ := file.ReadAt(buf1, int64(offset))
        offset = offset + len1
        if len1 == 0 {
            break
        }
        fmt.Println(string(buf1))
    }
    file.Close()
}
这是一个简单的打开文件读取数据的例子。
file.Read()方法是直接将文件内容读取到指定大小的byte数组中,由源码可知如果byte数组大于1G,那么默认一次最大可以读取1G大小的数据。
file.ReadAt()方法可以手动指定每次读取位置的偏移量。而不是默认设置。
我们再看OpenFile方法:
package main
import (
    "fmt"
    "os"
)
func main() {
    //以读写方式打开文件,如果不存在,则创建
    openFile, e := os.OpenFile("c:/1.txt", os.O_RDWR|os.O_CREATE, 777)
    if e != nil {
        fmt.Println(e)
    }
    buf := make([]byte,1024)
    for {
        len, _ := openFile.Read(buf)
        if len == 0 {
            break
        }
        fmt.Println(string(buf))
    }
    openFile.Close()
}
OpenFile函数的第二个参数是文件的打开模式:
const (
	// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
	O_RDONLY int = syscall.O_RDONLY // 只读模式
	O_WRONLY int = syscall.O_WRONLY //只写模式
	O_RDWR   int = syscall.O_RDWR   // 读写混合模式
	// The remaining values may be or'ed in to control behavior.
	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  // 打开文件时清空文件
)
前面三种是文件打开模式,后面五种是打开文件之后相应的操作模式;前面三个你只能选择一个,后面可以多选,中间用"|"隔开。
OpenFile函数的第三个参数是文件的权限,跟linux文件权限一致:
r ——> 004
w ——> 002
x ——> 001
通常情况如果你只是读文件操作,权限是可以被忽略的,第三个参数可以传0。而在写文件的时候,就需要传666,以确保你有足够的权限执行写入。
2. 写入文件
上面我们用到了OpenFile,可以指定文件打开的方式,如果使用了只写或者读写模式,表示可以写文件。另外control模式选择的不同对你写文件的影响也是大有不同的,比如:
|--------------------------------------------------------------------------------
os.O_RDWR|os.O_CREATE : 文件不存在会新建文件,文件如果存在,会从文件开始处用新内容覆盖原始内容,(如果新内容只有5个字符,原始内容有10个,那么只有开始5个是新内容,后面5个还是以前的内容)
os.O_RDWR|os.O_APPEND : 本次写入的值会在文件末尾进行append操作,不会覆盖以前的内容。
os.O_RDWR|os.O_TRUNC : 打开文件的时候先清空文件。
|-------------------------------------------------------------------------------
package main
import (
    "fmt"
    "os"
)
func main() {
    openFile, e := os.OpenFile("c:/1.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 777)
    if e != nil {
        fmt.Println(e)
    }
    str := "overwrite to file"
    openFile.WriteString(str)
    openFile.Close()
}
上面是打开文件写内容,当然我们也可以创建文件写内容:
package main
import (
    "bufio"
    "fmt"
    "os"
)
func main() {
    f, err := os.Create("c:/1.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    content := map[string]string{
        "hello": "111",
        "world": "222",
        "world1": "333",
        "world2": "444",
    }
    bw := bufio.NewWriter(f)
    for k, v := range content {
        bw.WriteString(k + ":" + v + "\n")
    }
    bw.Flush()
}
3. 使用bufio读取文件
上面演示了按照字节流去读文件的方式,Go还提供了一个io缓冲区:bufio,可以先将文件读取到缓冲区中,然后从缓冲区读取数据:
package main
import (
    "bufio"
    "fmt"
    "io"
    "os"
)
func main() {
    openFile, e := os.OpenFile("c:/1.txt", os.O_RDWR|os.O_CREATE, 777)
    if e != nil {
        fmt.Println(e)
    }
    reader := bufio.NewReader(openFile)
    //按行读取
    for {
       line, _, e := reader.ReadLine()
       if e == io.EOF {
           break
       }
       if e != nil {
           fmt.Println(e)
       }
       fmt.Println(string(line))
    }
    //按照指定分隔符读取
    for{
        s, e := reader.ReadString('\n')
        fmt.Println(s)
        if e == io.EOF {
            break
        }
        if e != nil {
            fmt.Println(e)
        }
    }
    openFile.Close()
}
4. 读取压缩文件
compress包提供了读取压缩文件的功能,支持的压缩文件格式为:bzip2、flate、gzip、lzw 和 zlib。
archive包提供了tar,zip格式的压缩解压缩功能。
package main
import (
    "archive/zip"
    "fmt"
    "io"
    "os"
    "strings"
)
//压缩文件
//files 文件数组,可以是不同dir下的文件或者文件夹
//dest 压缩文件存放地址
func Compress(files []*os.File, dest string) error {
    d, _ := os.Create(dest)
    defer d.Close()
    w := zip.NewWriter(d)
    defer w.Close()
    for _, file := range files {
        err := compress(file, "", w)
        if err != nil {
            return err
        }
    }
    return nil
}
func compress(file *os.File, prefix string, zw *zip.Writer) error {
    info, err := file.Stat()
    if err != nil {
        return err
    }
    if info.IsDir() {
        prefix = prefix + "/" + info.Name()
        fileInfos, err := file.Readdir(-1)
        if err != nil {
            return err
        }
        for _, fi := range fileInfos {
            f, err := os.Open(file.Name() + "/" + fi.Name())
            if err != nil {
                return err
            }
            err = compress(f, prefix, zw)
            if err != nil {
                return err
            }
        }
    } else {
        header, err := zip.FileInfoHeader(info)
        header.Name = prefix + "/" + header.Name
        if err != nil {
            return err
        }
        writer, err := zw.CreateHeader(header)
        if err != nil {
            return err
        }
        _, err = io.Copy(writer, file)
        file.Close()
        if err != nil {
            return err
        }
    }
    return nil
}
//解压
func DeCompress(zipFile, dest string) error {
    reader, err := zip.OpenReader(zipFile)
    if err != nil {
        return err
    }
    defer reader.Close()
    for _, file := range reader.File {
        rc, err := file.Open()
        if err != nil {
            return err
        }
        defer rc.Close()
        filename := dest + file.Name
        err = os.MkdirAll(getDir(filename), 0666)
        if err != nil {
            return err
        }
        w, err := os.Create(filename)
        if err != nil {
            return err
        }
        defer w.Close()
        _, err = io.Copy(w, rc)
        if err != nil {
            return err
        }
        w.Close()
        rc.Close()
    }
    return nil
}
func getDir(path string) string {
    return subString(path, 0, strings.LastIndex(path, "/"))
}
func subString(str string, start, end int) string {
    rs := []rune(str)
    length := len(rs)
    if start < 0 || start > length {
        panic("start is wrong")
    }
    if end < start || end > length {
        panic("end is wrong")
    }
    return string(rs[start:end])
}
func main() {
    DeCompress("c:/1.zip","c:/")
    f1, err := os.Open("c:/1.txt")
    if err != nil {
        fmt.Println(err)
    }
    defer f1.Close()
    f2, err := os.Open("c:/2.txt")
    if err != nil {
        fmt.Println(err)
    }
    files := []*os.File{f1,f2}
    Compress(files,"c:/")
}
5.使用ioutil读写文件
ioutil包是Go官方给用户提供的一个io工具类,提供了一些封装好的方法让我们直接调用。
package main
import (
    "fmt"
    "io/ioutil"
)
func main() {
    //读取文件
    bytes, e := ioutil.ReadFile("c:/1.txt")
    if e != nil {
        fmt.Println(e)
    }
    fmt.Println(string(bytes))
    //读取文件夹
    infos, e := ioutil.ReadDir("c:/1")
    if e != nil {
        fmt.Println(e)
    }
    for _,v := range infos {
        fmt.Println(v.Name())
    }
    //向指定文件写入数据,如果文件不存在,则创建文件,写入数据之前清空文件
    ioutil.WriteFile("c:/1.txt", []byte("xxxxxxxxx"), 666)
    //在当前目录下,创建一个以test为前缀的临时文件夹,并返回文件夹路径
    name, e := ioutil.TempDir("c:/2", "tmp")
    fmt.Println(name)
    //在当前目录下,创建一个以test为前缀的文件,并以读写模式打开文件,并返回os.File指针
    f, e := ioutil.TempFile("c:/2", "tmpFile")
    f.WriteString("tmp word")
    f.Close()
}
Go中的文件读写的更多相关文章
- 【python系统学习17】python中的文件读写
		python中的文件读写 文件读写,是Python代码调用电脑文件的主要功能,能被用于读取和写入文本.音频片段.Excel文档.邮件以及任何保存在电脑上的东西. 可使用python批量的操作本地文件, ... 
- python中的文件读写(open()函数、with open('file_directory','r') as f:、read()函数等)
		python中也有文件读写,通过调用内置的读写函数.可以完成文件的打开/关闭.读.写入.追加等功能. open()函数 open()函数为python中的打开文件函数,使用方式为: f = open( ... 
- Android中的文件读写总结
		在Android中,文件主要分为两大类,内部存储和外部存储 内部存储的文件是程序私有的,分为普通文件和Cache文件 外部文件也可以是私有的,也可以是共有的,这要根据文件的目录位置来决定 共有文件可以 ... 
- Unity3d 在不同设备中的文件读写 的路径
		Application.dataPath : 数据路径 Unity Editor: <path tp project folder>/Assets Unity 编辑器:<工程文件 ... 
- Java中超大文件读写
		如果文件过大不能一次加载,就可以利用缓冲区: File file = new File(filepath); BufferedInputStream fis = new BufferedInputSt ... 
- python中文件读写
		读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘, ... 
- 快速入门Python中文件读写IO是如何来操作外部数据的?
		读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘, ... 
- python的文件读写笔记
		读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘, ... 
- python3:文件读写+with open as语句
		转载请表明出处:https://www.cnblogs.com/shapeL/p/9141238.html 前提:文中例子介绍test.json内容: hello 我们 326342 1.文件读取 ( ... 
随机推荐
- 003-python基础-字符类型
			基本数据类型(int,bool,str) 1.基本数据数据类型: int 整数 str 字符串. 一般不存放大量的数据 bool 布尔值. 用来判断. True, False list 列表.用来存放 ... 
- HDU 2896:病毒侵袭(AC自动机)
			http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:中文题意. 思路:AC自动机模板题.主要在于字符有128种,输出还要排序和去重! 注意是“total ... 
- 跟我学SpringCloud | 第十一篇:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪
			SpringCloud系列教程 | 第十一篇:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪 Springboot: 2.1.6.RELEASE SpringCloud: ... 
- 小代学Spring Boot之开篇
			想要获取更多文章可以访问我的博客 - 代码无止境. 前情提要 小代是一名入职不久的程序员,公司同事都亲切的称他小代.有一天小代的老大陈BOSS和小代说,公司后端最近准备换技术框架了. 小代: 换成啥? ... 
- nio原理和示例代码
			我正在为学习大数据打基础中,为了手撸rpc框架,需要懂得nio的原理,在搞懂nio框架前,我会带着大家手撸一些比较底层的代码,当然今后当我们学会了框架,这些繁琐的代码也就不用写了,但是学一学底层的代码 ... 
- 通过Spring整合hibernate并进行单元测试(详细)
			一. 没有基础hibernate基础的可以点击这里 ---------->ORM----hibernate入门Demo(无敌详细版) 这里我就不详细介绍了.. 二. hibernat.cfg.x ... 
- kuangbin专题专题四 Heavy Transportation POJ - 1797
			题目链接:https://vjudge.net/problem/POJ-1797 思路:请参考我列出的另一个题目,和这个题目要求的值相反,另一个清楚后,这个写的解释就明白了. 另一个类似题目的博客:h ... 
- Socket编程(C语言实现):socket()函数英文翻译
			最近开始研究使用Socket API来网络编程,想着把自己的感想.感悟写下来.我发现在编程之外还有不少概念性的东西要学习.我觉得应该有以下几点吧: 1.得了解下计算机网络的基本概念,如OSI的7层模型 ... 
- WinForm控件之【MonthCalendar】
			基本介绍 日期月历控件,顾名思义用来主要用来展示月历,获取年份.月份.日期.时分秒信息等 常设置属性 FirstDayOfWeek:面板展示周期的循序,一周的第一天由从周几开始排列: MaxDate: ... 
- WinForm控件之【MaskedTextBox】
			基本介绍 掩码文本控件,使用掩码来区分用户输入文本是否正确. 常设置属性 BeepOnError:指示键入无效字符是控件是否发出系统提示音: CutCopyMaskFormat:设置控件文本值复制到剪 ... 
