fix: handle with read the empty file (#4258)

This commit is contained in:
JiChen 2024-07-20 22:01:13 +10:00 committed by GitHub
parent cf5b080fbe
commit 9de04ee035
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 62 additions and 3 deletions

View File

@ -35,6 +35,7 @@ func firstLine(file *os.File) (string, error) {
for {
buf := make([]byte, bufSize)
n, err := file.ReadAt(buf, offset)
if err != nil && err != io.EOF {
return "", err
}
@ -45,6 +46,10 @@ func firstLine(file *os.File) (string, error) {
}
}
if err == io.EOF {
return string(append(first, buf[:n]...)), nil
}
first = append(first, buf[:n]...)
offset += bufSize
}
@ -56,25 +61,34 @@ func lastLine(filename string, file *os.File) (string, error) {
return "", err
}
bf := int64(bufSize)
var last []byte
offset := info.Size()
for {
offset -= bufSize
if offset < 0 {
if offset < bufSize {
bf = offset
offset = 0
} else {
offset -= bf
}
buf := make([]byte, bufSize)
buf := make([]byte, bf)
n, err := file.ReadAt(buf, offset)
if err != nil && err != io.EOF {
return "", err
}
if n == 0 {
return "", nil
}
if buf[n-1] == '\n' {
buf = buf[:n-1]
n--
} else {
buf = buf[:n]
}
for n--; n >= 0; n-- {
if buf[n] == '\n' {
return string(append(buf[n+1:], last...)), nil
@ -82,5 +96,9 @@ func lastLine(filename string, file *os.File) (string, error) {
}
last = append(buf, last...)
if offset == 0 {
return string(last), nil
}
}
}

View File

@ -52,6 +52,7 @@ last line`
second line
last line
`
emptyContent = ``
)
func TestFirstLine(t *testing.T) {
@ -79,6 +80,26 @@ func TestFirstLineError(t *testing.T) {
assert.Error(t, err)
}
func TestFirstLineEmptyFile(t *testing.T) {
filename, err := fs.TempFilenameWithText(emptyContent)
assert.Nil(t, err)
defer os.Remove(filename)
val, err := FirstLine(filename)
assert.Nil(t, err)
assert.Equal(t, "", val)
}
func TestFirstLineWithoutNewline(t *testing.T) {
filename, err := fs.TempFilenameWithText(longLine)
assert.Nil(t, err)
defer os.Remove(filename)
val, err := FirstLine(filename)
assert.Nil(t, err)
assert.Equal(t, longLine, val)
}
func TestLastLine(t *testing.T) {
filename, err := fs.TempFilenameWithText(text)
assert.Nil(t, err)
@ -99,6 +120,16 @@ func TestLastLineWithLastNewline(t *testing.T) {
assert.Equal(t, longLine, val)
}
func TestLastLineWithoutLastNewline(t *testing.T) {
filename, err := fs.TempFilenameWithText(longLine)
assert.Nil(t, err)
defer os.Remove(filename)
val, err := LastLine(filename)
assert.Nil(t, err)
assert.Equal(t, longLine, val)
}
func TestLastLineShort(t *testing.T) {
filename, err := fs.TempFilenameWithText(shortText)
assert.Nil(t, err)
@ -123,3 +154,13 @@ func TestLastLineError(t *testing.T) {
_, err := LastLine("/tmp/does-not-exist")
assert.Error(t, err)
}
func TestLastLineEmptyFile(t *testing.T) {
filename, err := fs.TempFilenameWithText(emptyContent)
assert.Nil(t, err)
defer os.Remove(filename)
val, err := LastLine(filename)
assert.Nil(t, err)
assert.Equal(t, "", val)
}