我找不到文件。围棋中的ReadLine函数。
如何一行一行地读取文件?
我找不到文件。围棋中的ReadLine函数。
如何一行一行地读取文件?
当前回答
在Go 1.16的新版本中,我们可以使用包嵌入来读取文件内容,如下所示。
package main
import _"embed"
func main() {
//go:embed "hello.txt"
var s string
print(s)
//go:embed "hello.txt"
var b []byte
print(string(b))
//go:embed hello.txt
var f embed.FS
data, _ := f.ReadFile("hello.txt")
print(string(data))
}
欲了解更多详情,请访问https://tip.golang.org/pkg/embed/ 和 https://golangtutorial.dev/tips/embed-files-in-go/
其他回答
// strip '\n' or read until EOF, return error if read error
func readline(reader io.Reader) (line []byte, err error) {
line = make([]byte, 0, 100)
for {
b := make([]byte, 1)
n, er := reader.Read(b)
if n > 0 {
c := b[0]
if c == '\n' { // end of line
break
}
line = append(line, c)
}
if er != nil {
err = er
return
}
}
return
}
在Go 1.1和更新版本中,最简单的方法是使用bufio.Scanner。下面是一个简单的例子,从文件中读取行:
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
file, err := os.Open("/path/to/file.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
// optionally, resize scanner's capacity for lines over 64K, see next example
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
这是从Reader中逐行读取的最干净的方法。
这里有一个警告:当行长度超过65536个字符时,Scanner将出错。如果你知道你的行长大于64K,使用Buffer()方法来增加扫描仪的容量:
...
scanner := bufio.NewScanner(file)
const maxCapacity int = longLineLen // your required line length
buf := make([]byte, maxCapacity)
scanner.Buffer(buf, maxCapacity)
for scanner.Scan() {
...
另一种方法是使用io/ioutil和strings库来读取整个文件的字节,将它们转换为字符串,并使用“\n”(换行符)字符作为分隔符来分割它们,例如:
import (
"io/ioutil"
"strings"
)
func main() {
bytesRead, _ := ioutil.ReadFile("something.txt")
fileContent := string(bytesRead)
lines := strings.Split(fileContent, "\n")
}
从技术上讲,您不是逐行读取文件,但是您可以使用这种技术解析每一行。此方法适用于较小的文件。如果您试图解析一个大型文件,请使用逐行读取的技术之一。
扫描*功能是伟大的用户在这里。下面是go-lang docs中稍微修改过的单词扫描器示例,用于扫描文件中的行。
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// An artificial input source.
const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n"
scanner := bufio.NewScanner(strings.NewReader(input))
// Set the split function for the scanning operation.
scanner.Split(bufio.ScanLines)
// Count the lines.
count := 0
for scanner.Scan() {
fmt.Println(scanner.Text())
count++
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading input:", err)
}
fmt.Printf("%d\n", count)
}
编辑:从go1.1开始,惯用的解决方案是使用bufio。扫描仪
我写了一种从文件中轻松读取每一行的方法。Readln(*bufio. reader)函数的作用是:从底层bufio返回一行(sans \n)。读者结构。
// Readln returns a single line (without the ending \n)
// from the input buffered reader.
// An error is returned iff there is an error with the
// buffered reader.
func Readln(r *bufio.Reader) (string, error) {
var (isPrefix bool = true
err error = nil
line, ln []byte
)
for isPrefix && err == nil {
line, isPrefix, err = r.ReadLine()
ln = append(ln, line...)
}
return string(ln),err
}
您可以使用Readln从文件中读取每一行。下面的代码读取文件中的每一行,并将每一行输出到标准输出。
f, err := os.Open(fi)
if err != nil {
fmt.Printf("error opening file: %v\n",err)
os.Exit(1)
}
r := bufio.NewReader(f)
s, e := Readln(r)
for e == nil {
fmt.Println(s)
s,e = Readln(r)
}
干杯!