Lire le fichier texte dans un tableau de chaînes (et écrire)

La capacité de lire (et d'écrire) un fichier texte dans un tableau de chaînes qui est, je crois, une assez exigence commune. Il est également très utile lors du démarrage d'un langage supprimant le besoin d'accéder initialement à une base de données. Existe-t-il à Golang?
par exemple

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

Et

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

Je préférerais utiliser un existant plutôt que de dupliquer.

81
go
demandé sur Himanshu 2011-05-04 17:27:08

5 réponses

À partir de la version Go1.1, Il y a un bufio.Scanner API qui peut facilement lire des lignes à partir d'un fichier. Considérons l'exemple suivant ci-dessus, réécrit avec 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)
  }
}
92
répondu Kyle Lemons 2016-08-02 12:03:27

Si le fichier n'est pas trop volumineux, cela peut être fait avec les fonctions ioutil.ReadFile et strings.Split comme ceci:

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

, Vous pouvez lire la documentation sur ioutil et cordes paquets.

105
répondu yanatan16 2012-10-05 03:37:05

Impossible de mettre à jour la première réponse.
Quoi qu'il en soit, après la sortie de Go1, il y a quelques changements de rupture, donc j'ai mis à jour comme indiqué ci-dessous:

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)
}
30
répondu Bill.Zhuang 2016-08-02 12:03:57

Vous pouvez utiliser os.Fichier (qui implémente l'e / s .Lecteur interface) avec le paquet bufio pour cela. Cependant, ces paquets sont construits avec une utilisation de la mémoire fixe à l'esprit (quelle que soit la taille du fichier) et sont assez rapides.

Malheureusement, cela rend la lecture du fichier entier dans la mémoire un peu plus compliquée. Vous pouvez utiliser un octets.Buffer {[5] } pour joindre les parties de la ligne si elles dépassent la limite de ligne. De toute façon, je vous recommande d'essayer d'utiliser la ligne lecteur directement dans votre projet (surtout si vous ne savez pas quelle est la taille du fichier texte!). Mais si le fichier est petit, l'exemple suivant peut vous suffire:

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)
    }
}

Une Autre solution pourrait être d'utiliser io.ioutil.ReadAll pour lire dans le fichier complet à la fois et faire le découpage par ligne après. Je ne vous donne pas un exemple explicite de la façon d'écrire les lignes dans le fichier, mais c'est essentiellement un os.Create() suivi d'une boucle similaire à celle de l'exemple (voir main()).

18
répondu tux21b 2012-01-14 09:51:31
func readToDisplayUsingFile1(f *os.File){
    defer f.Close()
    reader := bufio.NewReader(f)
    contents, _ := ioutil.ReadAll(reader)
    lines := strings.Split(string(contents), '\n')
}

Ou

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)
    }
2
répondu msoliman 2013-12-08 14:54:32