go系列-读取文件

news2024/11/24 6:29:12

1 概述

2 整个文件读入内存

直接将数据直接读取入内存,是效率最高的一种方式,但此种方式,仅适用于小文件,对于大文件,则不适合,因为比较浪费内存。

2.1 直接指定文化名读取

在 Go 1.16 开始,ioutil.ReadFile 就等价于 os.ReadFile,二者是完全一致的。

2.1.1 os.ReadFile函数

package main
 
import (
    "fmt"
    "os"
)
 
func main() {
   //func ReadFile(name string) ([]byte, error) {}
    content, err := os.ReadFile("a.txt")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(content))
}

2.1.2 ioutil.ReadFile函数

package main
 
import (
    "io/ioutil"
    "fmt"
)
 
func main() {
    content, err := ioutil.ReadFile("a.txt")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(content))
}

2.2 先创建句柄再读取

2.2.1 os.OpenFile函数

package main
 
import (
"os"
"io/ioutil"
"fmt"
)
 
func main() {
    /*func Open(name string) (*File, error) {
    return OpenFile(name, O_RDONLY, 0)
     }*/
     //Open是一个高级函数,是因为它是只读模式来打开文件
     /*也可以直接使用 os.OpenFile,只是要多加两个参数
       file, err := os.OpenFile("a.txt", os.O_RDONLY, 0)*/
    file, err := os.Open("a.txt")
    if err != nil {
        panic(err)
    }
    //func (f *File) Close() error {}
    defer file.Close()
    //func ReadAll(r io.Reader) ([]byte, error) {}
    content, err := ioutil.ReadAll(file)
    fmt.Println(string(content))
}

2.2.2 代码解析

2.2.2.1 os.File结构体

1

2

3

type File struct {

    *file // os specific

}

2.2.2.2 os.OpenFile函数

1

2

func OpenFile(name string, flag int, perm FileMode) (

    *File,   error) {}

2.2.2.3 io.Reader接口

1

2

3

type Reader interface {

    Read(p []byte) (n int, err error)

}

3 每次只读取一行

一次性读取所有的数据,太耗费内存,因此可以指定每次只读取一行数据,方法有三种:

  • bufio.ReadLine()
  • bufio.读取字节("\n")
  • bufio.ReadString("\n")

在 bufio 的源码注释中,曾说道 bufio.ReadLine()是低级库,不太适合普通用户使用,更推荐用户使用 bufio.ReadBytes和bufio.ReadString 去读取单行数据。

3.1 使用bufio.Reader结构体的ReadBytes方法读取字节数

 ReadBytes读取直到第一次遇到delim字节,返回一个包含已读取的数据和delim字节的切片。如果ReadBytes方法在读取到delim之前遇到了错误,它会返回在错误之前读取的数据以及该错误(一般是io.EOF)。当且仅当ReadBytes方法返回的切片不以delim结尾时,会返回一个非nil的错误。

package main
 
import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
)
 
func main() {
    // 创建句柄
    fi, err := os.Open("christmas_apple.py")
    if err != nil {
        panic(err)
    }
    //func NewReader(rd io.Reader) *Reader {},返回的是bufio.Reader结构体
    r := bufio.NewReader(fi)// 创建 Reader
 
    for {
    //func (b *Reader) ReadBytes(delim byte) ([]byte, error) {}
        lineBytes, err := r.ReadBytes('\n')
        //去掉字符串首尾空白字符,返回字符串
        line := strings.TrimSpace(string(lineBytes))
        if err != nil && err != io.EOF {
            panic(err)
        }
        if err == io.EOF {
            break
        }
        fmt.Println(line)
    }
}

3.2 使用bufio.Reader结构体的ReadString方法读取字符串

ReadString读取直到第一次遇到delim字节,返回一个包含已读取的数据和delim字节的字符串。如果ReadString方法在读取到delim之前遇到了错误,它会返回在错误之前读取的数据以及该错误(一般是io.EOF)。当且仅当ReadString方法返回的切片不以delim结尾时,会返回一个非nil的错误。

package main
 
import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
)
 
func main() {
    // 创建句柄
    fi, err := os.Open("a.txt")
    if err != nil {
        panic(err)
    }
 
    // 创建 Reader
    r := bufio.NewReader(fi)
 
    for {
    //func (b *Reader) ReadString(delim byte) (string, error) {}
        line, err := r.ReadString('\n')
        line = strings.TrimSpace(line)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if err == io.EOF {
            break
        }
        fmt.Println(line)
    }
}

3.3 代码解析

3.3.1 bufio.Reader结构体

type Reader struct {
    buf          []byte
    rd           io.Reader // reader provided by the client
    r, w         int       // buf read and write positions
    err          error
    lastByte     int // last byte read for UnreadByte; -1 means invalid
    lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
}

4 每次只读取固定字节数

每次仅读取一行数据,可以解决内存占用过大的问题,但要注意的是,并不是所有的文件都有换行符 \n;
因此对于一些不换行的大文件来说,还得再想想其他办法

4.1 使用os库

通用的做法是:

  1. 先创建一个文件句柄,可以使用 os.Open 或者 os.OpenFile;
  2. 然后 bufio.NewReader 创建一个 Reader;
  3. 然后在 for 循环里调用 Reader 的 Read 函数,每次仅读取固定字节数量的数据。

Read方法读取数据写入p;本方法返回写入p的字节数;本方法一次调用最多会调用下层Reader接口一次Read方法,因此返回值n可能小于len§;读取到达结尾时,返回值n将为0而err将为io.EOF。

package main
 
import (
    "bufio"
    "fmt"
    "io"
    "os"
)
 
func main() {
    // 创建句柄
    fi, err := os.Open("a.txt")
    if err != nil {
        panic(err)
    }
 
    // 创建 Reader
    r := bufio.NewReader(fi)
 
    // 每次读取 1024 个字节
    buf := make([]byte, 1024)
    for {
        //func (b *Reader) Read(p []byte) (n int, err error) {}
        n, err := r.Read(buf)
        if err != nil && err != io.EOF {
            panic(err)
        }
 
        if n == 0 {
            break
        }
        fmt.Println(string(buf[:n]))
    }
}

4.2 使用 syscall库

os 库本质上也是调用 syscall 库,但由于 syscall 过于底层,如非特殊需要,一般不会使用 syscall;

package main
 
import (
    "fmt"
    "sync"
    "syscall"
)
 
func main() {
    fd, err := syscall.Open("christmas_apple.py", syscall.O_RDONLY, 0)
    if err != nil {
        fmt.Println("Failed on open: ", err)
    }
    defer syscall.Close(fd)
 
    var wg sync.WaitGroup
    wg.Add(2)
    dataChan := make(chan []byte)
    go func() {
        wg.Done()
        for {
            data := make([]byte, 100)
            n, _ := syscall.Read(fd, data)
            if n == 0 {
                break
            }
            dataChan <- data
        }
        close(dataChan)
    }()
 
    go func() {
        defer wg.Done()
        for {
            select {
            case data, ok := <-dataChan:
                if !ok {
                    return
                }
 
                fmt.Printf(string(data))
            default:
 
            }
        }
    }()
    wg.Wait()
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/685368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python编程语言制作的著名游戏

Python编程语言制作的著名游戏 Python是一种广泛使用的编程语言&#xff0c;其简单易读的语法让其成为许多游戏开发者的首选。本文将介绍利用Python编程语言制作的几个著名游戏&#xff0c;并将着重标记加粗它们的标题&#xff0c;以便于读者更容易了解。 1. 游戏&#xff1a…

【Python】python入门篇

概述 官网 https://www.python.org/ Python 是一种脚本语言&#xff08;scripting language&#xff09;。 与编译型语言&#xff08;如 C 和 C&#xff09;不同&#xff0c;Python 的程序代码不需要进行显式的编译&#xff0c;在执行时会动态地解释执行代码。 Python 的脚本执…

FFmpeg 解码 AAC 格式的音频

FFmpeg 默认是可以解码 AAC 格式的音频&#xff0c;但是如果需要获取 PCM16 此类数据则需要经过音频转码。首先要打开解码器&#xff0c;然后向解码器发送 AAC 音频帧&#xff08;不带 ADTS&#xff09;&#xff0c;然后从解码器获取解码后的音频帧&#xff0c;数据是 float 类…

【软考网络管理员】2023年软考网管初级常见知识考点(12)-应用层协议

涉及知识点 应用层协议详解&#xff0c;DNS的概念&#xff0c;FTP的概念&#xff0c;DHCP的概念&#xff0c;Telnet的概念&#xff0c;电子邮件协议 软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于&#xff1a;CSDN博主…

我的内网渗透-代理转发(2)

目录 ssh telnet与SSH的区别 安装环境 常用参数 本地端口转发 远程端口转发 动态端口转发 Socks 使用方法 msf端口转发 常用参数 使用方法 创建监听 MSF读取文件命令&#xff08;开启msf的时候直接读取文件就自动设置好监听的各种配置&#xff09; 获取会话后 …

NCI Core Control Messages

NCI 版本参数应编码为 8 位字段&#xff0c;由两个 4 位无符号值组成&#xff0c;表示本规范的主要和次要版本级别。 最高有效 4 位应表示主要版本级别。 最低有效 4 位应表示本规范的次要版本级别。 如果 DH 支持 NFCC 报告的主要版本&#xff0c;则 DH 应继续通信&#xff0…

同比增长超300%,「手势识别」前装赛道借势多模态座舱交互

在座舱多模态交互系统中&#xff0c;手势识别功能正在成为主流的配置之一。高工智能汽车研究院监测数据显示&#xff0c;2022年中国市场&#xff08;不含进出口&#xff09;乘用车前装标配手势识别功能交付37.39万辆&#xff1b;今年1-4月交付23.90万辆&#xff0c;同比增长超过…

Linux下的free、uname、uptime、netstat、dmesg指令

文章目录 1 查看内存的使用情况&#xff1a;free2 查看系统与内核相关信息&#xff1a;uname3 查看系统运行时间和负载&#xff08;uptime&#xff09;4 查看端口监听&#xff1a;netstat5 分析内核产生的信息&#xff1a;dmesg 1 查看内存的使用情况&#xff1a;free free -m…

C++进阶—二叉搜索树

目录 0. 前言 1. 二叉搜索树概念 2. 二叉搜索树操作 3. 二叉搜索树的实现 3.1 非递归实现插入操作Insert 3.2 二叉搜索树中序遍历递归实现&#xff08;排序&#xff09; 3.3 非递归实现查找操作Find 3.4 非递归实现删除操作Erase 3.5 递归实现插入操作InsertR 3.5 递…

c++读取文件之---yaml-cpp使用

实际项目总会遇到有很多超参数的情况&#xff0c;用常规的结构体等无法有效的涵盖所有&#xff0c;为了方便用户进行配置使用&#xff0c;因此使用yaml的方式进行编辑配置&#xff0c;因此去调研使用了yaml-cpp的使用方法。 1、yaml-cpp下载和编译 下载方式很简单&#xff0c…

openfeign实现远程调用

一 openfeign简介 Feign 是声明性(注解)web 服务客户端它使编写 web 服务客户端更加容易请创建一个接口并对其进行注解.它具有可插入注解支持&#xff0c;包括Feign注解和JAXRS注解Feign 还支持可插拔编码器和解码器。Spring cloud 添加了对Spring MVC注解的支持&#xff0c;并…

chatgpt赋能python:Python编译成SO文件和反编译的介绍

Python编译成SO文件和反编译的介绍 什么是SO文件&#xff1f; SO文件&#xff0c;也称为共享对象文件&#xff0c;是一种二进制文件格式&#xff0c;用于在多个应用程序之间共享代码和数据。在Unix和类Unix系统中&#xff0c;它们通常是共享库文件的形式。因此&#xff0c;SO…

chatgpt赋能python:Python编译成可执行文件:让你的代码更加优雅高效

Python编译成可执行文件&#xff1a;让你的代码更加优雅高效 Python作为世界上最受欢迎的编程语言之一&#xff0c;拥有着丰富的库、面向对象的语法和简单易懂的语法结构。然而&#xff0c;在开发Python应用程序时&#xff0c;受限于Python的解释性&#xff0c;导致程序的效率…

Qt实现自定义控件能够以插件的方式加载到Qt设计师

目录 1、自定义部件/控件2、改进法3、插件法3.1、创建工程3.2、工程目录3.3、修改插件类的代码3.3.1、HexSpinBox类的头文件3.3.2、HexSpinBox类的源文件3.3.3、HexSpinBox类的UI文件3.3.4 需要的注意的事项 3.4、生成动态库 4、测试插件能否正常使用4.1、测试Qt设计师能否识别…

认识@Validated 和 @Valid

对于web应用来说&#xff0c;对方法参数的校验是十分重要的&#xff0c;参数校验的是否全面&#xff0c;直接决定整个方法的健壮性。 除了使用麻烦的if判断校验参数&#xff0c;还可以使用Validated 和 Valid注解来进行优雅地参数校验&#xff0c;让参数校验和写诗一样优雅。 …

手机移动 APP测试流程及测试点

1 APP测试基本流程 1.1 流程图 1.2 测试周期 测试周期可按项目的开发周期来确定测试时间&#xff0c; 一般测试时间为两三 周(即 15 个工作日)&#xff0c;根据项目情况以及版本质量可适当缩短或延长 测试时间。正式测试前先向主管确认项目排期。 1.3 测试资源 测试任务开始…

移动云智能算力调度平台,谱写算力互联互通新篇章

中国移动算力网络建设取得新进展&#xff01;移动云智能算力调度平台验证了多云服务商间异构算力的统一调度能力&#xff0c;联动国家级超算中心、智算中心&#xff0c;促进东部业务灵活使用西部算力&#xff0c;作为未来算力互联网的统一调度平台将持续开展技术攻关与应用创新…

linux系统LNMP架构部署

文章目录 一、Nginx编译安装1、关闭防火墙&#xff0c;安全机制2、安装依赖包3、创建运行用户与组4、解压包、编译安装路径5、编译安装6、优化路径7、添加 Nginx 系统服务、赋权 二、安装 MySQL 服务1、安装环境依赖包2、创建运行用户与组3、解压包、编译安装路径4.编译安装5、…

chatgpt赋能python:用Python编程计算BMI,轻松掌握健康

用Python编程计算BMI&#xff0c;轻松掌握健康 作为一个现代人&#xff0c;保持健康的体态是我们每个人都需要关注的问题。那么&#xff0c;如何快速地计算自己的BMI呢&#xff1f;Python编程可以帮助我们轻松地实现这个目标。 什么是BMI&#xff1f; BMI全称为Body Mass In…

【Linux操作系统】互斥的4个概念以及认识信号量

文章目录 进程互斥的4个概念认识信号量认识接口理解IPC 信号量主要用于同步和互斥的&#xff0c;下面先来看看什么是同步和互斥。 进程互斥的4个概念 我们把大家都能看到的资源&#xff0c;称为公共资源。并且要想实现进程间通信&#xff0c;首要条件就是要让互相通信的进程看…