mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
18c7c67308
- pkg/useragent - pkg/units - pkg/ulimit - pkg/truncindex - pkg/timeoutconn - pkg/term - pkg/tarsum - pkg/tailfile - pkg/systemd - pkg/stringutils - pkg/stringid - pkg/streamformatter - pkg/sockets - pkg/signal - pkg/proxy - pkg/progressreader - pkg/pools - pkg/plugins - pkg/pidfile - pkg/parsers - pkg/parsers/filters - pkg/parsers/kernel - pkg/parsers/operatingsystem Signed-off-by: Vincent Demeester <vincent@sbr.pm>
66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
// Package tailfile provides helper functinos to read the nth lines of any
|
|
// ReadSeeker.
|
|
package tailfile
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
const blockSize = 1024
|
|
|
|
var eol = []byte("\n")
|
|
|
|
// ErrNonPositiveLinesNumber is an error returned if the lines number was negative.
|
|
var ErrNonPositiveLinesNumber = errors.New("The number of lines to extract from the file must be positive")
|
|
|
|
//TailFile returns last n lines of reader f (could be a fil).
|
|
func TailFile(f io.ReadSeeker, n int) ([][]byte, error) {
|
|
if n <= 0 {
|
|
return nil, ErrNonPositiveLinesNumber
|
|
}
|
|
size, err := f.Seek(0, os.SEEK_END)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
block := -1
|
|
var data []byte
|
|
var cnt int
|
|
for {
|
|
var b []byte
|
|
step := int64(block * blockSize)
|
|
left := size + step // how many bytes to beginning
|
|
if left < 0 {
|
|
if _, err := f.Seek(0, os.SEEK_SET); err != nil {
|
|
return nil, err
|
|
}
|
|
b = make([]byte, blockSize+left)
|
|
if _, err := f.Read(b); err != nil {
|
|
return nil, err
|
|
}
|
|
data = append(b, data...)
|
|
break
|
|
} else {
|
|
b = make([]byte, blockSize)
|
|
if _, err := f.Seek(step, os.SEEK_END); err != nil {
|
|
return nil, err
|
|
}
|
|
if _, err := f.Read(b); err != nil {
|
|
return nil, err
|
|
}
|
|
data = append(b, data...)
|
|
}
|
|
cnt += bytes.Count(b, eol)
|
|
if cnt > n {
|
|
break
|
|
}
|
|
block--
|
|
}
|
|
lines := bytes.Split(data, eol)
|
|
if n < len(lines) {
|
|
return lines[len(lines)-n-1 : len(lines)-1], nil
|
|
}
|
|
return lines[:len(lines)-1], nil
|
|
}
|