[file] Go를 사용하여 파일을 읽고 쓰는 방법?

Go를 스스로 배우려고 노력했지만 일반 파일을 읽고 쓰는 데 어려움을 겪었습니다.

나는까지 얻을 수 inFile, _ := os.Open(INFILE, 0, 0)있지만 실제로는 파일의 내용을 얻는 것이 의미가 없습니다. 읽기 함수는 []byte매개 변수로 사용 하기 때문 입니다.

func (file *File) Read(b []byte) (n int, err Error)



답변

Go에서 파일을 읽고 쓰는 모든 방법의 Go 1 호환 목록을 만들어 봅시다.

파일 API가 최근 변경되었으며 대부분의 다른 답변은 Go 1에서 작동하지 않기 때문에 bufio중요한 IMHO가 누락되었습니다 .

다음 예제에서는 파일을 읽고 대상 파일에 기록하여 파일을 복사합니다.

기본으로 시작

package main

import (
    "io"
    "os"
)

func main() {
    // open input file
    fi, err := os.Open("input.txt")
    if err != nil {
        panic(err)
    }
    // close fi on exit and check for its returned error
    defer func() {
        if err := fi.Close(); err != nil {
            panic(err)
        }
    }()

    // open output file
    fo, err := os.Create("output.txt")
    if err != nil {
        panic(err)
    }
    // close fo on exit and check for its returned error
    defer func() {
        if err := fo.Close(); err != nil {
            panic(err)
        }
    }()

    // make a buffer to keep chunks that are read
    buf := make([]byte, 1024)
    for {
        // read a chunk
        n, err := fi.Read(buf)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if n == 0 {
            break
        }

        // write a chunk
        if _, err := fo.Write(buf[:n]); err != nil {
            panic(err)
        }
    }
}

여기 내가 사용 os.Open하고 os.Create있는 편리한 래퍼 주위 os.OpenFile. 우리는 일반적으로 OpenFile직접 전화 할 필요가 없습니다 .

EOF 취급 통지. 각 호출 Read을 채우려 고 시도하고 파일 끝에 도달하면 오류로 buf반환합니다 io.EOF. 이 경우 buf여전히 데이터를 보유합니다. 결과적인 호출 Read은 읽은 바이트 수로 0 을 리턴 io.EOF하며 오류 와 동일 합니다. 다른 오류가 있으면 공황 상태가됩니다.

사용 bufio

package main

import (
    "bufio"
    "io"
    "os"
)

func main() {
    // open input file
    fi, err := os.Open("input.txt")
    if err != nil {
        panic(err)
    }
    // close fi on exit and check for its returned error
    defer func() {
        if err := fi.Close(); err != nil {
            panic(err)
        }
    }()
    // make a read buffer
    r := bufio.NewReader(fi)

    // open output file
    fo, err := os.Create("output.txt")
    if err != nil {
        panic(err)
    }
    // close fo on exit and check for its returned error
    defer func() {
        if err := fo.Close(); err != nil {
            panic(err)
        }
    }()
    // make a write buffer
    w := bufio.NewWriter(fo)

    // make a buffer to keep chunks that are read
    buf := make([]byte, 1024)
    for {
        // read a chunk
        n, err := r.Read(buf)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if n == 0 {
            break
        }

        // write a chunk
        if _, err := w.Write(buf[:n]); err != nil {
            panic(err)
        }
    }

    if err = w.Flush(); err != nil {
        panic(err)
    }
}

bufio데이터와 관련이 많지 않기 때문에 여기서는 버퍼 역할 만합니다. 대부분의 다른 상황 (특히 텍스트 파일) bufio은 장면 뒤의 버퍼링을 처리하는 동안 쉽고 유연하게 읽고 쓸 수 있는 멋진 API 를 제공함으로써 매우 유용 합니다.

사용 ioutil

package main

import (
    "io/ioutil"
)

func main() {
    // read the whole file at once
    b, err := ioutil.ReadFile("input.txt")
    if err != nil {
        panic(err)
    }

    // write the whole body at once
    err = ioutil.WriteFile("output.txt", b, 0644)
    if err != nil {
        panic(err)
    }
}

파이처럼 쉬워요! 그러나 큰 파일을 다루지 않는 것이 확실한 경우에만 사용하십시오.


답변

이것은 좋은 버전입니다.

package main

import (
  "io/ioutil";
  )


func main() {
  contents,_ := ioutil.ReadFile("plikTekstowy.txt")
  println(string(contents))
  ioutil.WriteFile("filename", contents, 0644)
}


답변

사용 io.Copy

package main

import (
    "io"
    "log"
    "os"
)

func main () {
    // open files r and w
    r, err := os.Open("input.txt")
    if err != nil {
        panic(err)
    }
    defer r.Close()

    w, err := os.Create("output.txt")
    if err != nil {
        panic(err)
    }
    defer w.Close()

    // do the actual work
    n, err := io.Copy(w, r)
    if err != nil {
        panic(err)
    }
    log.Printf("Copied %v bytes\n", n)
}

당신은 바퀴를 개혁 기분하지 않는 경우, io.Copy그리고 io.CopyN잘 서비스를 제공 할 수 있습니다. io.Copy 함수 의 소스확인 하면 Go 라이브러리에 패키지 된 Mostafa 솔루션 (실제로는 ‘기본’솔루션) 중 하나 일뿐입니다. 그러나 그는 자신보다 훨씬 큰 버퍼를 사용하고 있습니다.


답변

최신 Go 버전을 사용하면 파일을 쉽게 읽고 쓸 수 있습니다. 파일에서 읽으려면 :

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    data, err := ioutil.ReadFile("text.txt")
    if err != nil {
        return
    }
    fmt.Println(string(data))
}

파일에 쓰려면 :

package main

import "os"

func main() {
    file, err := os.Create("text.txt")
    if err != nil {
        return
    }
    defer file.Close()

    file.WriteString("test\nhello")
}

파일의 내용을 덮어 씁니다 (없는 경우 새 파일을 만듭니다).


답변

[]byte바이트 배열의 일부 또는 전부의 슬라이스 (하위 문자열과 유사)입니다. 당신이 사용하여 액세스 할 수 조각의 길이 및 용량에 대한 찾습니다 시스템 및 배열 (슬라이스)의 모든 액세스 또는 일부를 더한 필드에 숨겨진 포인터 필드 값의 구조와 조각의 생각 len()cap()기능을 .

바이너리 파일을 읽고 인쇄하는 스타터 키트는 다음과 같습니다. inName시스템의 작은 파일을 참조 하려면 리터럴 값 을 변경 해야합니다.

package main
import (
    "fmt";
    "os";
)
func main()
{
    inName := "file-rw.bin";
    inPerm :=  0666;
    inFile, inErr := os.Open(inName, os.O_RDONLY, inPerm);
    if inErr == nil {
        inBufLen := 16;
        inBuf := make([]byte, inBufLen);
        n, inErr := inFile.Read(inBuf);
        for inErr == nil {
            fmt.Println(n, inBuf[0:n]);
            n, inErr = inFile.Read(inBuf);
        }
    }
    inErr = inFile.Close();
}


답변

이 시도:

package main

import (
  "io";
  )


func main() {
  contents,_ := io.ReadFile("filename");
  println(string(contents));
  io.WriteFile("filename", contents, 0644);
}


답변

문서를 보면 그냥 [] byte 유형의 버퍼를 선언하고 읽은 다음 전달하여 많은 문자를 읽고 실제로 읽은 문자 수를 반환해야합니다 (오류).

문서는 말합니다

읽기는 파일에서 len (b) 바이트까지 읽습니다. 읽은 바이트 수와 오류 (있는 경우)를 반환합니다. EOF는 err가 EOF로 설정된 0 카운트로 신호됩니다.

작동하지 않습니까?

편집 : 또한 os 를 사용하는 대신 bufio 패키지에 선언 된 Reader / Writer 인터페이스를 사용해야한다고 생각합니다. 패키지 합니다.