-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathread.go
66 lines (53 loc) · 1.45 KB
/
read.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package ioline
import (
"os"
)
// Line represents a single file line with buffers for the lines before and after it
type Line struct {
FirstLine int
Before []string
Exact string
After []string
}
// Count the total number of lines
func (line Line) Count() int {
return 1 + len(line.Before) + len(line.After)
}
// ReadFile gets the specified line from the file at the provided path
func ReadFile(path string, currentLine int) (string, error) {
line, err := ReadFileWithBuffers(path, currentLine, 0, 0)
return line.Exact, err
}
// ReadFileWithBuffers returns the specified line with a buffer of lines before and after it
func ReadFileWithBuffers(path string, currentLine int, beforeLinesAmount int, afterLinesAmount int) (Line, error) {
lastLine := currentLine + afterLinesAmount
firstLine := currentLine - beforeLinesAmount
if firstLine < 0 {
firstLine = 1
}
lines := Line{FirstLine: firstLine}
file, err := os.Open(path)
defer file.Close()
if err != nil {
return lines, err
}
scanner := NewScanner(file)
lineIndex := 1
for scanner.Next() {
line := scanner.Get()
if scanner.Error() != nil {
return lines, scanner.Error()
}
if lineIndex >= firstLine && lineIndex < currentLine {
lines.Before = append(lines.Before, line)
}
if lineIndex == currentLine {
lines.Exact = line
}
if lineIndex > currentLine && lineIndex <= lastLine {
lines.After = append(lines.After, line)
}
lineIndex++
}
return lines, nil
}