인프런 쉽고 빠르게 끝내는 GO언어 프로그래밍 핵심 기초 입문 과정 강의 정리
11.1 파일 입출력
11.1.1 os 패키지 - 파일 읽기, 쓰기
Go에서 파일을 읽고 쓰기 위해 Go 표준 패키지인 os 패키지를 사용할 수 있다.
os.Open()
: 기존 파일 열기
os.Create()
: 새 파일을 생성
os.Close()
: 파일 리소스 닫기
파일 읽기 및 탐색 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package main
import (
"fmt"
"os"
)
// 에러 체크 방식 1
func errCheck1(e error) {
if e != nil {
panic(e)
}
}
// 에러 체크 방식 2
func errCheck2(e error) {
if e != nil {
fmt.Println(e)
return
}
}
func main() {
// 파일 열기
file, err := os.Open("section11/sample.txt")
errCheck1(err)
// 읽기 예제 1
fileInfo, err := file.Stat() // 파일 사이즈 확인 위해 정보 획득
errCheck2(err)
fd1 := make([]byte, fileInfo.Size()) // 슬라이스에 읽은 내용 담는다.
ct1, err := file.Read(fd1)
fmt.Println("파일 정보 출력 1 => ", fileInfo, "\n")
fmt.Println("파일 이름 1 => ", fileInfo.Name(), "\n")
fmt.Println("파일 크기 1 => ", fileInfo.Size(), "\n")
fmt.Println("파일 수정 시간 1 =>", fileInfo.ModTime(), "\n")
fmt.Printf("읽기 작업 완료 1 => (%d bytes) \n\n", ct1)
fmt.Println(string(fd1))
// 읽기 예제 2 (탐색 : Seek(offset))
o1, err := file.Seek(20, 0) // 0 : 처음위치, 1: 현재위치 2: 마지막위치
errCheck2(err)
fd2 := make([]byte, 20)
ct2, err := file.Read(fd2)
errCheck2(err)
fmt.Printf("읽기 작업 완료 2 => (%d bytes) (%d ret)\n\n", ct2, o1)
fmt.Println(string(fd2))
// 읽기 예제 3
o2, err := file.Seek(0, 0)
errCheck2(err)
fd3 := make([]byte, 50)
ct3, err := file.ReadAt(fd3, 8) // offset
errCheck1(err)
fmt.Printf("읽기 작업 완료 2 => (%d bytes) (%d ret)\n\n", ct3, o2)
fmt.Println(string(fd3))
defer file.Close()
}
|
파일 쓰기 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
package main
import (
"fmt"
"os"
)
// 에러 체크 방식 1
func errCheck1(e error) {
if e != nil {
panic(e)
}
}
// 에러 체크 방식 2
func errCheck2(e error) {
if e != nil {
fmt.Println(e)
return
}
}
// 파일 쓰기 1
func main() {
// 파일 쓰기 예제
file, err := os.Create("test_write.txt")
errCheck1(err)
// 리소스 해제
defer file.Close()
// 쓰기 예제
s1 := []byte{115, 111, 109, 101, 111}
n1, err := file.Write([]byte(s1)) // 문자열 -> byte 슬라이스 형으로 변환 후 쓰기
errCheck2(err)
fmt.Printf("File Write Result : (%d bytes)\n", n1)
file.Sync() // Write Commit (Stable)!
// 쓰기 예제 2
s2 := "Hello GoLang! \n File Write Test - 1 \n"
n2, err := file.WriteString(s2)
errCheck2(err)
fmt.Printf("File Write Result(2) : (%d bytes)\n", n2)
file.Sync()
// 쓰기 예제 3
s3 := "Test WriteAt ! - 2 \n"
n3, err := file.WriteAt([]byte(s3), 70) // len(offset) 조절하면서 테스트
errCheck1(err)
fmt.Printf("File Write Result(3) : (%d bytes)\n", n3)
file.Sync()
// 쓰기 예제 4
n4, err := file.WriteString("Hello GoLang! \n File Write Test! - 3\n")
errCheck2(err)
fmt.Printf("File Write Result(4) : (%d bytes)\n", n4)
}
|
11.1.2 CSV 파일 읽기
- 패키지 저장소를 통해 Excel 등 다양한 파일 형식 쓰기, 읽기가 가능하다.
bufio
: 파일이 용량이 클 경우 버퍼 사용을 권장한다.
- 사용패키지 : tealeg/xlsx
csv 파일 읽기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
package main
import (
"bufio"
"encoding/csv"
"fmt"
"os"
)
func errCheck(e error) {
if e != nil {
panic(e)
}
}
func main() {
// 파일 생성
file, err := os.Open("section11/sample.csv")
errCheck(err)
// 리소스 해제
defer file.Close()
// CSV Reader 생성
//rr := csv.NewReader(file)
rr := csv.NewReader(bufio.NewReader(file)) // 권장
// CSV 내용 읽기
row, err := rr.Read() // 1개의 Row 단위로 읽기
errCheck(err)
row2, err2 := rr.Read() // 1개의 Row 단위로 읽기
errCheck(err2)
fmt.Println("CSV Read Example")
fmt.Println(row[0], row[1], row[2])
fmt.Println(row2[0], row2[1], row2[2])
fmt.Println(row[0:5])
fmt.Println("=================================")
rows, err := rr.ReadAll() // 전체 Row Read
errCheck(err)
fmt.Println("CSV Read All Example")
fmt.Println(rows)
fmt.Println(rows[5][1])
// Row 단위로 CSV 파일 읽기
for i, row := range rows {
// fmt.Println(i, row)
for j := range row {
fmt.Printf("%s ", rows[i][j])
}
fmt.Println()
}
}
|
csv 파일 쓰기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
package main
import (
"encoding/csv"
"fmt"
"os"
_ "bufio"
)
// 에러 체크 방식 1
func errCheck1(e error) {
if e != nil {
panic(e)
}
}
// 에러 체크 방식 2
func errCheck2(e error) {
if e != nil {
fmt.Println(e)
return
}
}
func main() {
// 파일 생성
file, err := os.Create("test_write.csv")
errCheck1(err)
// 리소스 해제
defer file.Close()
// CSV Writer 생성
wr := csv.NewWriter(file)
// wr := csv.NewWriter(bufio.NewWriter(file))
// csv 내용 쓰기
wr.Write([]string{"KIM", "4.8"})
wr.Write([]string{"LEE", "4.2"})
wr.Write([]string{"PARK", "4.1"})
wr.Write([]string{"CHO", "4.0"})
wr.Write([]string{"HONG", "4.2"})
wr.Flush() // 버퍼 -> 파일로 쓰기
fi, err := file.Stat()
errCheck1(err)
fmt.Printf("CSV 쓰기 작업 후 파일 크기 (%d bytes)\n", fi.Size())
fmt.Println("CSV 파일명 : ", fi.Name())
fmt.Println("운영 체제 파일 권한 : ", fi.Mode())
}
|
11.1.3 ioutil 패키지를 활용
파일 퍼미션
ioutil 활용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package main
import (
"fmt"
"io/ioutil"
"os"
)
func errCheck(e error) {
if e != nil {
panic(e)
}
}
func main() {
s := "Hello Golang!\n File Write Test!\n"
// 파일 쓰기
err := ioutil.WriteFile("test_write1.txt", []byte(s), os.FileMode(0644))
errCheck(err)
// 파일 읽기
data, err := ioutil.ReadFile("section11/sample.txt")
errCheck(err)
fmt.Println("=============================================")
fmt.Println(string(data))
fmt.Println("=============================================")
}
|
11.1.5 파일 버퍼사용
1
2
3
4
5
6
7
|
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
|
버퍼의 사용
1
2
3
4
5
6
7
8
9
10
11
|
상태
a ------> a
b ------> ab
c ------> abc
d ------> abcd // 버퍼가 꽉찰경우 버퍼를 비우고 파일을 쓴다.
e ------> e -------> abcd
f ------> ef -------> abcd
g ------> efg -------> abcd
h ------> efgh --------> abcd
i ------> i -------> abcdefg
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
package main
import (
"bufio"
"fmt"
"os"
)
func errCheck(e error) {
if e != nil {
panic(e)
}
}
func main() {
file, err := os.OpenFile("test_write2.txt", os.O_CREATE|os.O_RDWR, os.FileMode(0777))
// bufio 파일 쓰기 예제
wt := bufio.NewWriter(file) // Writer 반환한다. - 버퍼사용
wt.WriteString("Hello Golang!\nFile Write Test!\n")
wt.Write([]byte("Hello Golang!\nFile Write Test222!\n"))
// Error Check
errCheck(err)
// 버퍼 정보 출력
fmt.Printf("사용한 Buffer Size : (%d Bytes)\n", wt.Buffered())
fmt.Printf("남은 Buffer Size : (%d Bytes)\n", wt.Available())
fmt.Printf("전체 Buffer Size : (%d Bytes)\n", wt.Size())
wt.Flush() // 버퍼 비우고 디스크 반영 (버퍼의 내용을 디스크에 기록한다.)
fmt.Println("쓰기 작업 완료 \n")
fmt.Println("=================================================")
rt := bufio.NewReader(file) // Reader 반환
fi, err := file.Stat()
errCheck(err)
b := make([]byte, fi.Size())
fmt.Println("파일 정보 출력 : ", fi)
fmt.Println("파일 이름: ", fi.Name())
fmt.Println("파일 크기 : ", fi.Size())
fmt.Println("파일 수정시간 : ", fi.ModTime())
fmt.Println("=================================================")
fmt.Println()
file.Seek(0, os.SEEK_SET)
data, _ := rt.Read(b) // 읽기(ReadLine, ReadByte, ReadBytes 등)
// rt.Read(b)
fmt.Printf("전체 Buffer Szie : (%d Bytes)\n", rt.Size())
fmt.Printf("읽기 작업 완료 (%d Bytes) \n", data)
fmt.Println("=================================================")
fmt.Println(string(b))
fmt.Println("=================================================")
defer file.Close()
}
|