Bir dosyayı dize değişkenine nasıl okuyabilirim


161

Çok sayıda küçük dosyam var, bunları satır satır okumak istemiyorum.

Go'da tüm dosyayı dize değişkenine okuyacak bir işlev var mı?

Yanıtlar:


253

Kullanım ioutil.ReadFile:

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

ReadFile, dosyaadı adlı dosyayı okur ve içeriği döndürür. Başarılı bir çağrı err == nil döndürür, err == EOF değerini döndürür. ReadFile tüm dosyayı okuduğundan, Read'den bir EOF'a rapor edilecek bir hata olarak davranmaz.

Bunun []byteyerine bir string. Gerçekten gerekliyse dönüştürülebilir :

s := string(buf)

5
Daha sonra son dize sonucunu oluşturmak için, her dosyayı okurken verileri tek bir bayt diliminde biriktirmek için append () öğesini kullanabilir, ardından biriken bayt dilimini son dize sonucuna dönüştürebilirsiniz. Alternatif olarak bytes.Join.
Sonia

1
Bize nasıl dönüştürüleceğini göster ... Soru bir bayt dizisi istemiyor.
Kyle Bridenstine

Bir html dosyasını açmak için bunu kullanarak ve ben biçimlendirme bazı karışıklık her satırdan sonra yeni bir satır eklendi bulabilirsiniz. Bundan kaçınmanın bir yolu var mı?
Jonathan

55

İçeriği sadece istediğiniz gibi istiyorsanız, stringbasit çözüm ReadFileişlevi io/ioutilpaketten kullanmaktır. Bu işlev bytes, kolayca a dönüştürebileceğiniz bir dilim döndürür 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

Bence en iyi şey, eğer tüm bu dosyaları birleştirme verimliliği gerçekten endişe, hepsini aynı bayt arabellek kopyalamak olduğunu düşünüyorum.

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

Bu, her dosyayı açar, içeriğini buf'e kopyalar, ardından dosyayı kapatır. Durumunuza bağlı olarak, dönüştürmeniz gerekmeyebilir, son satır sadece buf.Bytes () öğesinin aradığınız verilere sahip olduğunu göstermektir.


Merhaba, io.Copy buf içeriğinin üzerine yazacak mı? Peki buferin kapasitesi nedir? Teşekkürler.
WoooHaaaa

Kopyaların üzerine yazılmaz, sadece buf'e eklemeye devam eder ve buf, yeni verileri karşılamak için gerektiği kadar büyür.
Wild

1
Bufinin "sonsuz" bir kapasitesi vardır. Daha fazla veri eklendikçe genişlemeye devam edecektir. ioutil.Readfile, tüm dosyaya sığacak kadar büyük olan ve yeniden konumlandırılması gerekmeyen bir arabellek ayırır.
Stephen Weinberg

1
Bir bytebuffer kullanmak, performansı sadece dilim (/ diziye) eklemeye kıyasla gerçekten geliştiriyor mu? Hafıza ne olacak? Fark ne kadar büyük?
Kissaki

8

Ben böyle yaptım:

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

Bilgisayarla değilim, bu yüzden bir taslak yazıyorum. Söylediklerimden net olabilirsiniz.

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()
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.