Remove first line from text file in Golang

huangapple go评论48阅读模式
英文:

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 &lt; 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 (
&quot;bytes&quot;
&quot;fmt&quot;
&quot;io&quot;
&quot;os&quot;
)
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(&#39;\n&#39;)
if err != nil &amp;&amp; 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(&quot;pop:&quot;, 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>

huangapple
  • 本文由 发表于 2015年6月19日 22:05:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/30940190.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定