ファイル全体を文字列変数に読み込むにはどうすればよいですか


161

小さなファイルがたくさんあるので、それらを行ごとに読みたくありません。

Goにファイル全体を文字列変数に読み込む関数はありますか?

回答:


253

使用ioutil.ReadFile

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

ReadFileは、filenameで指定されたファイルを読み取り、その内容を返します。呼び出しが成功すると、err == EOFではなく、err == nilが返されます。ReadFileはファイル全体を読み取るため、ReadからのEOFを報告されるエラーとして扱いません。

[]byte代わりにを取得しstringます。本当に必要な場合変換できます。

s := string(buf)

5
次に、最終的な文字列結果を作成するために、append()を使用して、各ファイルを読み取るときにデータを1バイトスライスに蓄積し、蓄積されたバイトスライスを最終的な文字列結果に変換します。あるいは、bytes.Joinが好きかもしれません。
ソニア

1
それを変換する方法を教えてください...質問はバイト配列を求めていません。
Kyle Bridenstine

これを使用してhtmlファイルを開くと、改行がすべての行の後に追加されていることがわかります。それを回避する方法はありますか?
ジョナサン

55

内容stringをそのままにするReadFile場合は、io/ioutilパッケージの関数を使用するのが簡単な解決策です。この関数は、bytes簡単にに変換できるスライスを返します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

これらのファイルすべてを連結する効率を本当に心配している場合は、すべてを同じバイトバッファーにコピーするのが最善の方法だと思います。

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

これは、各ファイルを開き、その内容をbufにコピーしてから、ファイルを閉じます。実際の変換が不要な場合もありますが、最後の行は、buf.Bytes()に探しているデータがあることを示すだけです。


こんにちは、io.Copyはbufのコンテンツを上書きしますか?そしてbufの容量は何ですか?ありがとう。
WoooHaaaa

コピーは上書きされず、bufに追加され続けるだけであり、bufは新しいデータに対応するために必要なだけ大きくなります。
Wild

1
bufには「無限」の容量があります。より多くのデータが追加されるにつれて、それは拡大し続けます。ioutil.Readfileは、ファイル全体を収めるのに十分な大きさで、再割り当てする必要のないバッファを割り当てます。
Stephen Weinberg、

1
バイトバッファを使用すると、単にスライス(/配列)に追加する場合と比較して、本当にパフォーマンスが向上しますか?メモリはどうですか?違いはどのくらいですか?
Kissaki

8

これは私がそれをした方法です:

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

私はコンピューターを持っていないので、下書きを書きます。あなたは私の言うことをはっきりしているかもしれません。

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()
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.