使用go语言读取文件的各种方式整理。
一次性加载到内存中
- // * 整个文件读到内存,适用于文件较小的情况
- //每次读取固定字节
- //问题容易出现乱码,因为中文和中文符号不占一个字符
- func readAllIntoMemory(filename string) (content []byte, err error) {
- fp, err := os.Open(filename) // 获取文件指针
- if err != nil {
- return nil, err
- }
- defer fp.Close()
- fileInfo, err := fp.Stat()
- if err != nil {
- return nil, err
- }
- buffer := make([]byte, fileInfo.Size())
- _, err = fp.Read(buffer) // 文件内容读取到buffer中
- if err != nil {
- return nil, err
- }
- return buffer, nil
- }
复制代码 一次性加载到内存中适用于小文件。 如果文件太大, 内存紧张的情况下, 可以借助缓冲, 分多次读取。
分块读取
- // * 一块一块地读取, 即给一个缓冲, 分多次读到缓冲中
- //按字节读取,将整个文件读取到缓冲区buffer
- func readByBlock(filename string) (content []byte, err error) {
- fp, err := os.Open(filename) // 获取文件指针
- if err != nil {
- return nil, err
- }
- defer fp.Close()
- const bufferSize = 64 // 缓冲大小, 每次读取64个字节
- buffer := make([]byte, bufferSize)
- for {
- // 注意这里要取bytesRead, 否则有问题
- bytesRead, err := fp.Read(buffer) // 文件内容读取到buffer中
- content = append(content, buffer[:bytesRead]...)
- if err != nil {
- if err == io.EOF {
- err = nil
- break
- } else {
- return nil, err
- }
- }
- }
- return
- }
复制代码 有时我们也需要按行处理
按行读
- // 逐行读取, 一行是一个[]byte, 多行就是[][]byte
- func readByLine(filename string) (lines [][]byte, err error) {
- fp, err := os.Open(filename) // 获取文件指针
- if err != nil {
- return nil, err
- }
- defer fp.Close()
- bufReader := bufio.NewReader(fp)
- for {
- line, _, err := bufReader.ReadLine() // 按行读
- if err != nil {
- if err == io.EOF {
- err = nil
- break
- }
- } else {
- lines = append(lines, line)
- }
- }
- return
- }
复制代码 使用ioutil读取文件的所有内容
- func test1() {
- bytes,err := ioutil.ReadFile("filetoread.txt")
- if err != nil {
- log.Fatal(err)
- }
- fmt.Println("total bytes read:",len(bytes))
- fmt.Println("string read:",string(bytes))
- }
复制代码
|