英文:
Remove first line from text file in Golang
问题
我正在尝试弹出文件的第一行,并逐行减少文件行数。
我删除第一行的实现如下:
type FS struct {
...
File *os.File
}
//文件创建正常...
func (fs *Fs) pop() []byte {
var buf []string
scanner := bufio.NewScanner(fs.File)
//读取每一行
for scanner.Scan() {
line := scanner.Text()
buf = append(buf, line)
}
//从第二行开始写入同一文件
for s := 1; s < len(buf); s++ {
fs.File.WriteString(fmt.Println(buf展开收缩))
}
//提交更改
fs.File.Sync()
fs.File.Close()
return []byte(buf[0])
}
我得到了预期字符串的返回[]byte,但文件从未更改。
我在这里漏掉了什么?
英文:
I'm trying to pop the first line of a file and thus reduce the file lines one by one.
My implementation for removing the first line is as follows
type FS struct {
...
File *os.File
}
//File creation ok...
func (fs *Fs) pop() []byte {
var buf []string
scanner := bufio.NewScanner(fs.File)
//Reading lines
for scanner.Scan() {
line := scanner.Text()
buf = append(buf, line)
}
//Writing from second line on the same file
for s := 1; s < len(buf); s++ {
fs.File.WriteString(fmt.Println(buf展开收缩))
}
//Commit changes
fs.File.Sync()
fs.File.Close()
return []byte(buf[0])
}
I get the returned []byte with the expected string but the file never changes.
What am I missing here?
答案1
得分: 8
将文件的第一行弹出,从而逐行减少文件的行数。
例如,
package main
import (
"bytes"
"fmt"
"io"
"os"
)
func popLine(f *os.File) ([]byte, error) {
fi, err := f.Stat()
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(make([]byte, 0, fi.Size()))
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
_, err = io.Copy(buf, f)
if err != nil {
return nil, err
}
line, err := buf.ReadBytes('\n')
if err != nil && err != io.EOF {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
nw, err := io.Copy(f, buf)
if err != nil {
return nil, err
}
err = f.Truncate(nw)
if err != nil {
return nil, err
}
err = f.Sync()
if err != nil {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
return line, nil
}
func main() {
fname := `popline.txt`
f, err := os.OpenFile(fname, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer f.Close()
line, err := popLine(f)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println("pop:", string(line))
}
$ cat popline.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
$ go run popline.go
pop: Lorem ipsum dolor sit amet, consectetur adipiscing elit,
$ cat popline.txt
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
$
英文:
> pop the first line of a file and thus reduce the file lines one by
> one.
For example,
package main
import (
"bytes"
"fmt"
"io"
"os"
)
func popLine(f *os.File) ([]byte, error) {
fi, err := f.Stat()
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(make([]byte, 0, fi.Size()))
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
_, err = io.Copy(buf, f)
if err != nil {
return nil, err
}
line, err := buf.ReadBytes('\n')
if err != nil && err != io.EOF {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
nw, err := io.Copy(f, buf)
if err != nil {
return nil, err
}
err = f.Truncate(nw)
if err != nil {
return nil, err
}
err = f.Sync()
if err != nil {
return nil, err
}
_, err = f.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
return line, nil
}
func main() {
fname := `popline.txt`
f, err := os.OpenFile(fname, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer f.Close()
line, err := popLine(f)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println("pop:", string(line))
}
<pre>
$ cat popline.txt
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
$ go run popline.go
pop: Lorem ipsum dolor sit amet, consectetur adipiscing elit,
$ cat popline.txt
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
$
</pre>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论