golang 文件操作io bufio ioutil

io

golang 文件操作io bufio ioutil

golang中 os.File 库封装了文件相关操作,File是一个结构体。

go语言标准库文档:https://studygolang.com/static/pkgdoc/pkg/os.htm#File

具体的使用:

1、打开文件
1)os.Open

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

1.1 os.Create 创建文件

f,err := os.Create( fileName )

defer f.Close()

if err !=nil {

  fmt.Println( err.Error() )

} else {

  _,err=f.Write([]byte("要写入的文本内容"))

  fmt.Println( err.Error() )

}

2)os.OpenFile

OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
① 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 // 如果可能,打开时清空文件 !!!谨慎使用!!!
)

② FileMode参数代表文件的模式和权限位,主要使用在Linux和Unix系统下,windows系统下无效。

const (
// 单字符是被String方法用于格式化的属性缩写。
ModeDir FileMode = 1 << (32 - 1 - iota) // d: 目录
ModeAppend // a: 只能写入,且只能写入到末尾
ModeExclusive // l: 用于执行
ModeTemporary // T: 临时文件(非备份文件)
ModeSymlink // L: 符号链接(不是快捷方式文件)
ModeDevice // D: 设备
ModeNamedPipe // p: 命名管道(FIFO)
ModeSocket // S: Unix域socket
ModeSetuid // u: 表示文件具有其创建者用户id权限
ModeSetgid // g: 表示文件具有其创建者组id的权限
ModeCharDevice // c: 字符设备,需已设置ModeDevice
ModeSticky // t: 只有root/创建者能删除/移动文件
// 覆盖所有类型位(用于通过&获取类型位),对普通文件,所有这些位都不应被设置
ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice
ModePerm FileMode = 0777 // 覆盖所有Unix权限位(用于通过&获取类型位)
)

2、关闭文件//Close关闭文件f,使文件不能用于读写。它返回可能出现的错误。

func (f *File) Close() error

//打开文件
file, err := os.Open("test.txt")
if err != nil {
    fmt.Println("open file err=", err)
}
fmt.Printf("file=%v", file) //这里打印出 file=&{0xc00007a780} ,因为file是一个指针

//关闭文件file,要及时关闭文件句柄file,防止内存泄漏
defer file.Close()

//关闭文件file,要及时关闭文件句柄file,防止内存泄漏
defer file.Close()
3、读取文件
1)读取到file中,再利用ioutil将file直接读取到[]byte中

例子:

func Read1() string {
    f, err := os.Open("./test.txt")
    if err != nil {
        fmt.Println("read file fail", err)
        return ""
    }
    defer f.Close()

    fd, err := ioutil.ReadAll(f)
    if err != nil {
        fmt.Println("read to fd fail", err)
        return ""
    }

    return string(fd)
}

2)io/ioutil包中的ReadFile方法一次性读取,适用于文件不大的情况下。

这种方式下文件的Open和Close被封装到ReadFile函数内部,直接读取即可。

例子:

func Read2() string {
f, err := ioutil.ReadFile(“./test.txt”)
if err != nil {
fmt.Println(“read fail”, err)
}
return string(f)
}
3)使用带缓冲区的方式

func Read3() string {
    file, err := os.Open("./basic/type/test.txt")
    if err != nil {
        fmt.Println("open file err=", err)
    }
    defer file.Close()

    var f string

    //创建一个 *Reader,带缓冲区的
    //默认缓冲区为defaultBufSize = 4096
    reader := bufio.NewReader(file)
    //循环读取文件内容
    for {
        str, err := reader.ReadString('\n')
        f += str
        if err == io.EOF { //io.EOF表示文件的末尾
            break
        }
    }

    return f
}

经验证,上面的’\n’ 对windows换行和linux都适用。

reader还有一个ReadLine的方法,不过是低阶api,上层封装是 ReadBytes(‘\n’) or ReadString(‘\n’).

func (*bufio.Reader).ReadLine() (line []byte , isPrefix bool , err error )

ReadLine is a low-level line-reading primitive. Most callers should use ReadBytes(‘\n’) or ReadString(‘\n’) instead or use a Scanner

问题:为什么

if err == io.EOF { /要放在后面。因为读取到最后一行(这行还有内容),这行返回的str有内容,但是err是EOF.ReadString("\n")应该是读到\n或EOF时返回,所以最后一行会返回EOF,但是你的代码中判断EOF后直接break了,此时line就是最后一行的内容

4、写入文件

func write1()  {
    filePath := "./basic/type/test1.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        fmt.Printf("open file err = %v\n", err)
        return
    }

    defer file.Close()

    //写入文件
    str := "hello world\r\n"
    writer := bufio.NewWriter(file)
    for i := 0; i < 5; i++ {
        writer.WriteString(str)
    }

    //writer是带缓存的,因此在调用writerString方法时,其实内存是先写入缓存的
    //Flush方法将缓存的数据真正写入文件中
    writer.Flush()
}

————————————————
参考链接:https://blog.csdn.net/lff1123/article/details/122747038

https://blog.csdn.net/weixin_37717557/article/details/106532544

Original: https://www.cnblogs.com/youxin/p/16214575.html
Author: youxin
Title: golang 文件操作io bufio ioutil

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/545994/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球