将文本文件读入字符串数组(并写入)

在字符串数组中读取(和写入)文本文件的能力是我认为相当常见的需求。如果从一种语言开始,就不再需要最初访问数据库,那么它也非常有用。Golang 有吗?
例如:。

func ReadLines(sFileName string, iMinLines int) ([]string, bool) {

还有

func WriteLines(saBuff[]string, sFilename string) (bool) {

我宁愿使用现有的而不是重复的。

161916 次浏览

可以将 os.File(实现 我是读者接口)与 Bufio包一起使用。但是,构建这些包时考虑到了固定的内存使用(无论文件有多大) ,并且速度非常快。

不幸的是,这使得将整个文件读入内存变得有点复杂。如果线路的各个部分超过了线路限制,则可以使用 字节缓冲区连接这些部分。无论如何,我建议您尝试在您的项目中直接使用行阅读器(特别是如果不知道文本文件有多大!).但是,如果文件较小,以下示例可能就足够了:

package main


import (
"os"
"bufio"
"bytes"
"fmt"
)


// Read a whole file into the memory and store it as array of lines
func readLines(path string) (lines []string, err os.Error) {
var (
file *os.File
part []byte
prefix bool
)
if file, err = os.Open(path); err != nil {
return
}
reader := bufio.NewReader(file)
buffer := bytes.NewBuffer(make([]byte, 1024))
for {
if part, prefix, err = reader.ReadLine(); err != nil {
break
}
buffer.Write(part)
if !prefix {
lines = append(lines, buffer.String())
buffer.Reset()
}
}
if err == os.EOF {
err = nil
}
return
}


func main() {
lines, err := readLines("foo.txt")
if err != nil {
fmt.Println("Error: %s\n", err)
return
}
for _, line := range lines {
fmt.Println(line)
}
}

另一种方法是使用 io.ioutil.ReadAll立即读入完整的文件,然后逐行进行切片。我没有给出一个明确的例子来说明如何将行写回文件,但是这基本上是一个 os.Create(),后面跟着一个类似于示例中的循环(参见 main())。

无法更新第一个答案。
无论如何,在 Go1发布后,有一些突破性的变化,所以我更新如下所示:

package main


import (
"os"
"bufio"
"bytes"
"io"
"fmt"
"strings"
)


// Read a whole file into the memory and store it as array of lines
func readLines(path string) (lines []string, err error) {
var (
file *os.File
part []byte
prefix bool
)
if file, err = os.Open(path); err != nil {
return
}
defer file.Close()


reader := bufio.NewReader(file)
buffer := bytes.NewBuffer(make([]byte, 0))
for {
if part, prefix, err = reader.ReadLine(); err != nil {
break
}
buffer.Write(part)
if !prefix {
lines = append(lines, buffer.String())
buffer.Reset()
}
}
if err == io.EOF {
err = nil
}
return
}


func writeLines(lines []string, path string) (err error) {
var (
file *os.File
)


if file, err = os.Create(path); err != nil {
return
}
defer file.Close()


//writer := bufio.NewWriter(file)
for _,item := range lines {
//fmt.Println(item)
_, err := file.WriteString(strings.TrimSpace(item) + "\n");
//file.Write([]byte(item));
if err != nil {
//fmt.Println("debug")
fmt.Println(err)
break
}
}
/*content := strings.Join(lines, "\n")
_, err = writer.WriteString(content)*/
return
}


func main() {
lines, err := readLines("foo.txt")
if err != nil {
fmt.Println("Error: %s\n", err)
return
}
for _, line := range lines {
fmt.Println(line)
}
//array := []string{"7.0", "8.5", "9.1"}
err = writeLines(lines, "foo2.txt")
fmt.Println(err)
}

Note: ioutil is deprecated as of Go 1.16.

如果文件不太大,可以使用 ioutil.ReadFilestrings.Split函数来实现,如下所示:

content, err := ioutil.ReadFile(filename)
if err != nil {
//Do something
}
lines := strings.Split(string(content), "\n")

您可以阅读关于 Ioutil绳子软件包的文档。

As of Go1.1 release, there is a Bufio 扫描器 API that can easily read lines from a file. Consider the following example from above, rewritten with Scanner:

package main


import (
"bufio"
"fmt"
"log"
"os"
)


// readLines reads a whole file into memory
// and returns a slice of its lines.
func readLines(path string) ([]string, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()


var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines, scanner.Err()
}


// writeLines writes the lines to the given file.
func writeLines(lines []string, path string) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()


w := bufio.NewWriter(file)
for _, line := range lines {
fmt.Fprintln(w, line)
}
return w.Flush()
}


func main() {
lines, err := readLines("foo.in.txt")
if err != nil {
log.Fatalf("readLines: %s", err)
}
for i, line := range lines {
fmt.Println(i, line)
}


if err := writeLines(lines, "foo.out.txt"); err != nil {
log.Fatalf("writeLines: %s", err)
}
}
func readToDisplayUsingFile1(f *os.File){
defer f.Close()
reader := bufio.NewReader(f)
contents, _ := ioutil.ReadAll(reader)
lines := strings.Split(string(contents), '\n')
}

或者

func readToDisplayUsingFile1(f *os.File){
defer f.Close()
slice := make([]string,0)


reader := bufio.NewReader(f)


for{


str, err := reader.ReadString('\n')
if err == io.EOF{
break
}


slice = append(slice, str)
}