Come posso leggere un intero file in una variabile stringa


161

Ho molti piccoli file, non voglio leggerli riga per riga.

Esiste una funzione in Go che leggerà un intero file in una variabile stringa?

Risposte:


253

Utilizzare ioutil.ReadFile:

func ReadFile(filename string) ([]byte, error)

ReadFile legge il file denominato dal nome file e restituisce il contenuto. Una chiamata riuscita restituisce err == zero, non err == EOF. Poiché ReadFile legge l'intero file, non considera un EOF di Read come un errore da segnalare.

Otterrai un []byteinvece di un string. Può essere convertito se veramente necessario:

s := string(buf)

5
Quindi per costruire il risultato della stringa finale, è possibile utilizzare append () per accumulare i dati in una singola porzione di byte mentre si legge ogni file, quindi convertire la porzione di byte accumulata nel risultato della stringa finale. In alternativa, potresti apprezzare i byte. Partecipa.
Sonia,

1
Mostraci come convertirlo, quindi ... La domanda non richiede un array di byte.
Kyle Bridenstine,

Usando questo per aprire un file html e trovo che una nuova riga viene aggiunta dopo ogni riga che ci sta rovinando un po 'della mia formattazione. C'è un modo per evitarlo?
Jonathan,

55

Se vuoi solo il contenuto come string, allora la soluzione semplice è usare la ReadFilefunzione dal io/ioutilpacchetto. Questa funzione restituisce una sezione di bytescui puoi facilmente convertire in a string.

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    b, err := ioutil.ReadFile("file.txt") // just pass the file name
    if err != nil {
        fmt.Print(err)
    }

    fmt.Println(b) // print the content as 'bytes'

    str := string(b) // convert content to a 'string'

    fmt.Println(str) // print the content as a 'string'
}

22

Penso che la cosa migliore da fare, se sei davvero preoccupato per l'efficienza della concatenazione di tutti questi file, sia copiarli tutti nello stesso buffer di byte.

buf := bytes.NewBuffer(nil)
for _, filename := range filenames {
  f, _ := os.Open(filename) // Error handling elided for brevity.
  io.Copy(buf, f)           // Error handling elided for brevity.
  f.Close()
}
s := string(buf.Bytes())

Questo apre ogni file, copia il suo contenuto in buf, quindi chiude il file. A seconda della situazione in cui potresti non aver bisogno di convertirla, l'ultima riga è solo per mostrare che buf.Bytes () ha i dati che stai cercando.


Ciao, io.Copy sovrascriverà il contenuto di buf? E qual è la capacità di buf? Grazie.
WoooHaaaa,

La copia non verrà sovrascritta, continuerà semplicemente ad aggiungersi a buf e buf crescerà tanto quanto è necessario per accogliere i nuovi dati.
esecuzione Wild il

1
Il buf ha una capacità "infinita". Continuerà ad espandersi man mano che vengono aggiunti più dati. ioutil.Readfile alloca un buffer abbastanza grande da adattarsi al file completo e non necessita di riallocare.
Stephen Weinberg,

1
L'uso di un bytebuffer migliora davvero le prestazioni rispetto al semplice aggiungerlo allo slice (/ array)? E la memoria? Quanto è grande la differenza?
Kissaki,

8

Ecco come l'ho fatto:

package main

import (
  "fmt"
  "os"
  "bytes"
  "log"
)

func main() {
   filerc, err := os.Open("filename")
   if err != nil{
     log.Fatal(err)
   }
   defer filerc.Close()

   buf := new(bytes.Buffer)
   buf.ReadFrom(filerc)
   contents := buf.String()

   fmt.Print(contents) 

}    

-2

Non sono con il computer, quindi scrivo una bozza. Potresti essere chiaro di quello che dico.

func main(){
    const dir = "/etc/"
    filesInfo, e := ioutil.ReadDir(dir)
    var fileNames = make([]string, 0, 10)
    for i,v:=range filesInfo{
        if !v.IsDir() {
            fileNames = append(fileNames, v.Name())
        }
    }

    var fileNumber = len(fileNames)
    var contents = make([]string, fileNumber, 10)
    wg := sync.WaitGroup{}
    wg.Add(fileNumber)

    for i,_:=range content {
        go func(i int){
            defer wg.Done()
            buf,e := ioutil.Readfile(fmt.Printf("%s/%s", dir, fileName[i]))
            defer file.Close()  
            content[i] = string(buf)
        }(i)   
    }
    wg.Wait()
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.