案例是:
我想在使用bufio.NewScanner作为行阅读器来读取行时获取字节
例如:
import ...
func main() {
f, err := os.Open("111.txt")
if err != nil {
log.Fatal(err)
}
f.Seek(0,os.SEEK_SET)
scan := bufio.NewScanner(f)
for scan.Scan() {
log.Printf(scan.Text())
//what I want is how many bytes at this time when I read a line
}//This is a program for read line
}
THX! ==================================更新=============== =========================== @twotwotwo这接近我想要的,但我想将 io.Reader 更改为 io.ReaderAt ,这就是我想要的,我写了一个演示使用 io.Reader :`
import (
"os"
"log"
"io"
)
type Reader struct {
reader io.Reader
count int
}
func (r *Reader) Read(b []byte) (int, error) {
n, err := r.reader.Read(b)
r.count += n
return n, err
}
func (r *Reader) Count() int {
return r.count
}
func NewReader(r io.Reader) *Reader {
return &Reader{reader: r}
}
func ReadLine(r *Reader) (ln int,line []byte,err error) {
line = make([]byte,0,4096)
for {
b := make([]byte,1)
n,er := r.Read(b)
if er == io.EOF {
err = er
break
}
if n > 0{
c := b[0]
if c == '\n' {
break
}
line = append(line, c)
}
if er != nil{
err = er
}
}
ln = r.Count()
return ln,line,err
}
func main() {
f, err := os.Open("111.txt")
if err != nil {
log.Fatal(err)
}
fi,_:=os.Stat("111.txt")
log.Printf("the file have %v bytes",fi.Size())
co := NewReader(f)
for {
count,line,er := ReadLine(co)
if er == io.EOF {
break
}
log.Printf("now read the line :%v",string(line))
log.Printf("in all we have read %v bytes",count)
}
}`
这个程序可以告诉我已经读过多少字节,但是无法从我想要的任何地方开始读取,所以我认为如果我们使用 io.ReaderAt 必须可以做到。 再次感谢!
答案 0 :(得分:0)
答案 1 :(得分:-1)
考虑构图。
我们知道bufio.NewScanner
通过io.Reader
接口与其输入进行交互。因此,我们可以使用其他东西来包装io.Reader
,以计算到目前为止已读取的字节数。
package main
import (
"bufio"
"bytes"
"io"
"log"
)
type ReadCounter struct {
io.Reader
BytesRead int
}
func (r *ReadCounter) Read(p []byte) (int, error) {
n, err := r.Reader.Read(p)
r.BytesRead += n
return n, err
}
func main() {
b := &ReadCounter{Reader: bytes.NewBufferString("hello\nworld\testing\n")}
scan := bufio.NewScanner(b)
for scan.Scan() {
log.Println(scan.Text())
log.Println("Read", b.BytesRead, "bytes so far")
}
}
但是我们会注意到bufio.NewScanner
是缓冲的,所以我们可以看到它以块的形式读取它的输入。因此,出于您的目的,这可能没有您想要的那么有用。
另一种方法是取scan.Text()
的内容并计算长度。您可以补偿其内部计数中的换行字节的删除。