답변:
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)
}
}
파이처럼 쉬워요! 그러나 큰 파일을 다루지 않는 것이 확실한 경우에만 사용하십시오.
panic("error in writing")
) 의 추가 검사 는 필요하지 않습니다.
이것은 좋은 버전입니다.
package main
import (
"io/ioutil";
)
func main() {
contents,_ := ioutil.ReadFile("plikTekstowy.txt")
println(string(contents))
ioutil.WriteFile("filename", contents, 0644)
}
0x777
가짜입니다. 어쨌든 더 비슷 0644
하거나 0755
(16 진수가 아닌 8 진수) 여야합니다 .
사용 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 솔루션 (실제로는 '기본'솔루션) 중 하나 일뿐입니다. 그러나 그는 자신보다 훨씬 큰 버퍼를 사용하고 있습니다.
w.Sync()
애프터io.Copy(w, r)
io.Copy()
쓰면 공급하는 데이터 만 쓰므로 기존 파일에 더 많은 내용이 있으면 제거되지 않으므로 파일이 손상 될 수 있습니다.
w, err := os.Create("output.txt")
"명명 된 파일을 만들거나 자릅니다 만듭니다. 파일이 이미 존재하는 경우가립니다."때문에, 당신은 무엇을 설명, 발생하지 않습니다 golang.org/pkg/os/#Create .
최신 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();
}
if
블록
이 시도:
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 인터페이스를 사용해야한다고 생각합니다. 패키지 합니다.
Read 메서드는 바이트 매개 변수를 사용합니다.이 매개 변수는 읽을 버퍼이기 때문입니다. 일부 서클에서는 일반적인 관용구이며 생각할 때 의미가 있습니다.
이 방법으로 독자가 읽을 바이트 수를 판별하고 실제로 읽은 바이트 수를 확인하고 오류를 적절하게 처리하기 위해 리턴을 검사 할 수 있습니다.
다른 사람들이 그들의 대답에서 지적했듯이 bufio는 아마도 대부분의 파일에서 읽으려는 것일 것입니다.
정말 유용하기 때문에 다른 힌트를 하나 추가하겠습니다. 파일에서 줄을 읽는 것은 ReadLine 메서드가 아니라 ReadBytes 또는 ReadString 메서드를 사용하는 것이 가장 좋습니다.