문제

나는 혼자서 가고 배우려고 노력했지만, 나는 일반 파일에서 읽고 글을 쓰려고 노력했다.

나는 멀리 얻을 수있다 inFile, _ := os.Open(INFILE, 0, 0), 그러나 실제로 파일의 내용을 얻는 것은 말이되지 않습니다. 읽기 기능이 []byte 매개 변수로.

func (file *File) Read(b []byte) (n int, err Error)
도움이 되었습니까?

해결책

파일을 읽고 쓰는 모든 방법의 1과 호환 목록을 작성해 보겠습니다.

File 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의 솔루션 중 하나 일뿐입니다. 그러나 그들은 자신보다 훨씬 더 큰 버퍼를 사용하고 있습니다.

[]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();
}

최신 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")
}

파일의 내용을 덮어 씁니다 (없으면 새 파일을 만듭니다).

이 시도:

package main

import (
  "io"; 
  )


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

문서를 살펴보면 [] 바이트의 버퍼를 선언하고 읽기로 전달한 다음 많은 문자를 읽고 실제로 읽는 문자 수 (및 오류)를 반환해야합니다.

문서 말하다

읽기는 파일에서 Len (B) 바이트까지 읽습니다. 바이트 읽기 수와 오류가 있으면 반환합니다. EOF는 ERR로 설정된 0 카운트로 신호를받습니다.

작동하지 않습니까?

편집 : 또한, 나는 당신이 아마도 부피오 사용하는 대신 패키지 OS 패키지.

읽기 메소드는 바이트 매개 변수를 취합니다. 왜냐하면 읽을 버퍼이기 때문입니다. 그것은 일부 서클의 일반적인 관용구이며 당신이 그것에 대해 생각할 때 의미가 있습니다.

이렇게하면 독자가 얼마나 많은 바이트를 읽을 것인지 결정하고 반환을 검사하여 실제로 얼마나 많은 바이트를 읽고, 오류를 적절하게 처리했는지 확인할 수 있습니다.

다른 사람들이 자신의 답변을 지적했듯이 Bufio는 아마도 대부분의 파일에서 읽기 위해 원하는 것일 것입니다.

정말 유용하기 때문에 다른 힌트를 추가하겠습니다. 파일에서 줄을 읽는 것은 Readline 메소드가 아니라 ReadBytes 또는 ReadString 메소드에 의해 가장 잘 수행됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top