如何统计Golang中bufio.Reader已读取的字节数?
统计bufio.Reader读取的字节数
根据你的需求,分两种场景给出解决方案:
场景1:统计转换后的UTF-8字节数
如果你要统计的是ReadString返回内容的UTF-8字节数(即经过UTF-16转UTF-8解码后的字节数),只需在每次读取后累加返回字符串的长度即可,注意要在调用TrimSpace之前统计,避免丢失空格对应的字节数:
file, err := os.Open(filepath) if err != nil { return nil, err } defer file.Close() utf16bom := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM) decoder := transform.NewReader(file, utf16bom.NewDecoder()) reader := bufio.NewReader(decoder) headerLines := make([]string, 0) var totalUTF8Bytes int64 for { line, err := reader.ReadString('\n') if err != nil { return nil, err } // 累加当前读取行的原始UTF-8字节数 totalUTF8Bytes += int64(len(line)) line = strings.TrimSpace(line) if strings.Contains(line, endOfSectionMark) { break } headerLines = append(headerLines, line) } // totalUTF8Bytes 即为已读取的UTF-8字节总数
场景2:统计底层文件的原始读取字节数
如果需要统计的是从原始文件中读取的UTF-16编码字节数(即解码前的字节数),由于transform.Decoder和bufio.Reader不会暴露该计数,需要自定义一个带计数功能的Reader包装器:
import "io" // countingReader 包装io.Reader,统计读取的字节数 type countingReader struct { src io.Reader count int64 } func (cr *countingReader) Read(p []byte) (int, error) { n, err := cr.src.Read(p) cr.count += int64(n) return n, err } // 修改原代码使用countingReader file, err := os.Open(filepath) if err != nil { return nil, err } defer file.Close() cr := &countingReader{src: file} utf16bom := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM) decoder := transform.NewReader(cr, utf16bom.NewDecoder()) reader := bufio.NewReader(decoder) headerLines := make([]string, 0) for { line, err := reader.ReadString('\n') if err != nil { return nil, err } line = strings.TrimSpace(line) if strings.Contains(line, endOfSectionMark) { break } headerLines = append(headerLines, line) } // cr.count 即为从底层文件读取的原始字节总数
内容的提问来源于stack exchange,提问作者adel
相关产品推荐
相关产品推荐

