duangouhui0446 2016-10-11 00:43
浏览 13
已采纳

如何使用Go编程语言进行练习

Exercise 7.5:
The LimitReader function in the io package accepts an io.Reader r and a number of bytes n, and returns another Reader that reads from r but reports an end-of-file condition after n bytes. Implement it.

func LimitReader(r io.Reader, n int64) io.Reader

How to implement it?


Below is my code, I know it not right.

type MyReader struct {
    bytes []byte
    length int
}

func (myReader *MyReader) Read (p []byte) (int, error) {
    fmt.Println("be invoked")
    myReader.bytes = p
    myReader.length = len(p)
    fmt.Printf("lenght: %d
" , myReader.length)
    return len(p), nil
}
func LimitReader(r io.Reader, n int64) io.Reader {
    filecontent, _:= ioutil.ReadFile("./testfile.txt")
    r.Read(filecontent[:n])
    return r
}

func main() {
    myReader := &MyReader{}
    r := LimitReader(myReader, 100)
    filecontent, _:= ioutil.ReadFile("./testfile.txt")
    fmt.Println(r.Read(filecontent))
}
  • 写回答

1条回答 默认 最新

  • drtj40036 2016-10-11 07:03
    关注

    It seems you are not clear with the concepts of what you need to do.

    You need to create a function with the following signature:

    func LimitReader(r io.Reader, n int64) io.Reader
    

    That is, an r io.Reader and an n number is passed to it, and you have to return a new io.Reader. When someone reads from the returned reader, the read data must come from the passed r reader, and it should automatically count the read bytes; and if the read bytes exceeds the n number, it must not read further bytes from r but return io.EOF which is used to indicate that the end of the stream is reached. It could be that the r reader has more bytes (meaning more bytes could be read from it), but that should not be read and returned: that's the purpose of the LimitedReader.

    If you think you understand the problem now, stop reading the answer for now, and try to implement this yourself. What follows is an example solution.


    This exact functionality already exists in the io package, and goes by the same name: io.LimitReader().

    // LimitReader returns a Reader that reads from r
    // but stops with EOF after n bytes.
    // The underlying implementation is a *LimitedReader.
    func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
    

    It returns a value of *io.LimitedReader, whose implementation is this:

    // A LimitedReader reads from R but limits the amount of
    // data returned to just N bytes. Each call to Read
    // updates N to reflect the new amount remaining.
    type LimitedReader struct {
        R Reader // underlying reader
        N int64  // max bytes remaining
    }
    
    func (l *LimitedReader) Read(p []byte) (n int, err error) {
        if l.N <= 0 {
            return 0, EOF
        }
        if int64(len(p)) > l.N {
            p = p[0:l.N]
        }
        n, err = l.R.Read(p)
        l.N -= int64(n)
        return
    }
    

    Take a minute or 2 to try to understand the code yourself. If you're stuck or not everything is clear, read on.

    Explaining the code:

    io.LimitedReader is a struct, which contains the source reader it reads from, and the number of bytes that can still be read without having to report io.EOF. So LimitReader() simply just returns a value of this struct where the parameters r and n are assigned to the fields R and N of the struct. More specifically an address of this struct is returned, because LimitedReader.Read() has pointer receiver, and so only a pointer to it implements io.Reader. And it has a pointer receiver, because the Read() method (may) modify the fields of the struct, so a pointer is required to be able to do that (else only a copy would be modified which is discarded after the Read() method returns).

    LimitedReader.Read() first checks the N field which tells how many more bytes can we return, and if there is no more "allowed", being a well-behaved Limited-reader, it returns io.EOF immedately without reading any more bytes from the source:

    if l.N <= 0 {
        return 0, EOF
    }
    

    If N is positive, that means some bytes may be read and returned, but no more than N, so if the p slice passed to Read() has a greater length, we re-slice it so a call to the source reader will not read more than what we should allow:

    if int64(len(p)) > l.N {
        p = p[0:l.N]
    }
    

    And the last part is nothing more that actually doing the reading, from the source reader:

    n, err = l.R.Read(p)
    

    Which returns the number of actually read bytes, and an optional error (whether reading encountered some error). Since we're about to return these, we have to administer that this amount of bytes are now returned, we have to subtract this from the allowed remaining bytes:

    l.N -= int64(n)
    return
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 tensorrt 推理 yolov8框出现错误
  • ¥15 用hc 05,做蓝牙控制小车 小车只能说初始遥控方向影响,后续不能更改
  • ¥15 51单片机怎么把每次输入键值保存到数组作为我的确认键的判断条件呢
  • ¥45 easy photo不能使用,求帮助
  • ¥15 c语言字符串单词入门问题报错
  • ¥30 我现在是双非人工智能专业不知道要不要转到软件工程专业
  • ¥15 请问12脉波整流机组的外特性曲线具体是如何推导
  • ¥15 abaqus里的python算法
  • ¥100 如何在思科模拟器中进入CEF模式
  • ¥15 Simulink 仿真如何使用MATLAB function模块获取到仿真过程中某一仿真时刻输入到模块的函数的值?