Чтение текстового файла в массив строк (и запись)



возможность чтения (и записи) текстового файла в строковый массив и из него я считаю довольно распространенным требованием. Это также очень полезно при запуске с языка, удаляющего необходимость первоначально обращаться к базе данных. Нет в Golang?

например,



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


и



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


Я бы предпочел использовать уже существующий, а не дублировать.

683   5  
go

5 ответов:

по состоянию на Go1.1 релиз, есть bufio.Сканер API, который может легко читать строки из файла. Рассмотрим следующий пример сверху, переписанный с помощью сканера:

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

Если файл не слишком большой, это можно сделать с помощью ioutil.ReadFile и strings.Split функции вот так:

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

вы можете прочитать документацию на ioutil и строки пакеты.

Не удается обновить первый ответ.
В любом случае, после выпуска 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)
}

можно использовать ОС.Файл (реализующий io.Читатель интерфейс) с bufio пакет для этого. Однако эти пакеты строятся с фиксированным использованием памяти (независимо от размера файла) и довольно быстро.

к сожалению, это делает чтение всего файла в память немного сложнее. Вы можете использовать байт.Буфер для соединения частей линии, если они превышают предел линии. Во Всяком Случае, Я рекомендуем попробовать использовать line reader непосредственно в вашем проекте (особенно если не знаете, насколько велик текстовый файл!). Но если файл небольшой, то вам может быть достаточно следующего примера:

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()).

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

Comments

    Ничего не найдено.