전체 파일을 문자열 변수로 읽는 방법


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 ()를 사용하여 각 파일을 읽을 때 단일 바이트 슬라이스로 데이터를 누적 한 다음 누적 바이트 슬라이스를 최종 문자열 결과로 변환 할 수 있습니다. 또는 바이트를 좋아할 수도 있습니다.
Sonia

1
변환하는 방법을 보여주세요 ... 질문은 바이트 배열을 요구하지 않습니다.
Kyle Bridenstine

이것을 사용하여 html 파일을 열면 모든 줄 뒤에 새 줄이 추가되어 내 서식 중 일부가 엉망이됩니다. 이를 피할 수있는 방법이 있습니까?
Jonathan

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
바이트 버퍼를 사용하면 슬라이스 (/ 배열)에 단순히 추가하는 것보다 성능이 실제로 향상됩니까? 메모리는 어떻습니까? 차이가 얼마나 큽니까?
사키

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.