>  기사  >  백엔드 개발  >  Go에서 생성기와 같은 \"tail -f\"를 어떻게 만들 수 있나요?

Go에서 생성기와 같은 \"tail -f\"를 어떻게 만들 수 있나요?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-01 03:24:28498검색

How Can I Create a

Go의 "tail -f"와 유사한 Generator

문제

Go에서 파일을 테일링하려면 다음을 사용하는 루프가 필요합니다. 오류가 발생하기 쉽고 비효율적일 수 있는 EOF에서의 절전 모드입니다. 이 작업을 수행하는 더 깔끔한 방법이 있나요?

해결책

고루틴을 사용하는 대신 EOF에서 대기하는 리더 주위에 래퍼를 만듭니다.

<code class="go">type tailReader struct {
    io.ReadCloser
}

func (t tailReader) Read(b []byte) (int, error) {
    for {
        n, err := t.ReadCloser.Read(b)
        if n > 0 {
            return n, nil
        } else if err != io.EOF {
            return n, err
        }
        time.Sleep(10 * time.Millisecond)
    }
}

func newTailReader(fileName string) (tailReader, error) {
    f, err := os.Open(fileName)
    if err != nil {
        return tailReader{}, err
    }

    if _, err := f.Seek(0, 2); err != nil {
        return tailReader{}, err
    }
    return tailReader{f}, nil
}</code>

사용법

이 리더는 bufio.Scanner 및 json.Decoder를 포함한 모든 io.Reader와 함께 사용할 수 있습니다. 예:

<code class="go">t, err := newTailReader(&quot;somefile&quot;)
if err != nil {
    log.Fatal(err)
}
defer t.Close()

// Use with bufio.Scanner
scanner := bufio.NewScanner(t)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

// Use with json.Decoder
dec := json.NewDecoder(t)
for {
    var v SomeType
    if err := dec.Decode(&amp;v); err != nil {
       log.Fatal(err)
    }
    fmt.Println(&quot;the value is &quot;, v)
}</code>

장점

  • 간편한 종료: 파일을 닫으면 됩니다.
  • 많은 패키지와 작동: 많은 패키지(예: bufio.Scanner 및 json.Decoder)가 io.Reader와 작동합니다.
  • 구성 가능한 절전: 대기 시간을 최적화하기 위해 절전 시간을 조정하거나 CPU 사용량.

위 내용은 Go에서 생성기와 같은 \"tail -f\"를 어떻게 만들 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.