본문 바로가기

프로그래밍/golang

[Golang] io 패키지 기초

 

1.  io.Copy

데이터를 원하는 목적지로 옮기는 표준 메서드

  • 왜 쓰는가? : 인메모리 폭주 방지 
    예 ) 1GB 데이터를 옮길 때 메모리를 1GB 사용하는게 아니라, 내부적으로 32KB 고정 버퍼만 사용해 데이터를 옮깁니다.
    데이터가 RAM에 쌓이지 않게 해 저사양 서버에서도 대용량을 처리 할 수 있도록 합니다.
func copyDemo() {
    src := strings.NewReader("Hello, Go World!\n")
    var dst bytes.Buffer
    io.Copy(&dst, src)
}

 

2.  io.TeeReader

데이터를 읽음과 동시에 다른 곳에 복사본 전달하는 T 자형 분기점 역할을 합니다.

  • 왜 쓰는가? : 일회성 데이터 재활용
    HTTP 요청의 바디처럼 한 번 읽으면 사라지는 데이터를 비즈니스 로직에서 처리하면 동시에 로그를 남기거나
    해시값을 계산할 때 사용합니다.
func teeDemo() {
    src := strings.NewReader("Important Data\n")
    var logBucket bytes.Buffer 

    r := io.TeeReader(src, &logBucket)

    data, _ := io.ReadAll(r)
    fmt.Print("Log:", logBucket.String())
}

 

3.  io.LimitReader

읽을 수 있는 데이터를 최대 크기로 강제 제한

  • 왜 쓰는가? : 보안 및 안정성
    사용자가 의도적이든 의도하지 않았던 서버에 무리가 올 정도의 큰 데이터를 전송하거나 공격의 목적으로 데이터를 전송한다면
    OOM(메모리 아웃)이 발생할 수 있는데, 이를 사전에 방지하는 역할을 합니다.
func limitDemo() {
    src := strings.NewReader("Very Large Data...")
    r := io.LimitReader(src, 4) 
    
    data, _ := io.ReadAll(r)
    fmt.Println("Result:", string(data))
}

 

4.  bufio

작은 단위의 입출력을 메모리에 모았다가 한 번에 처리합니다.

  • 왜 쓰는가? : I/O 성능 최적화
    1바이트씩 100번 쓰는 것보다, 100바이트 모아서 한 번에 쓰는 것이 운영체제 시스템 콜 횟수를 줄여 훨씬 빠릅니다.
    (예 : 로그 기록)
func bufioDemo() {
    var buf bytes.Buffer
    bw := bufio.NewWriter(&buf)
    
    bw.WriteString("Line A\n")
    bw.Flush()

    scanner := bufio.NewScanner(&buf)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

 

 

  1. 메모리 아끼고 싶습니다 -> io.Copy
  2. 처리하면서 로그 남기고 싶다 -> io.TeeReader
  3. 너무 큰 데이터는 거절하고 싶다 -> io.LimitReader
  4. 입출력 속도를 높이고 싶다 -> bufio

 

5. 전체 코드

https://github.com/reochoi109/go-handbook/blob/main/io/basic/main.go

 

go-handbook/io/basic/main.go at main · reochoi109/go-handbook

A personal handbook of Go patterns and best practices. Lightweight, practical code snippets for real-world backend development. - reochoi109/go-handbook

github.com

 

6. 참고자료

https://gobyexample.com/reading-files

 

Go by Example: Reading Files

Reading and writing files are basic tasks needed for many Go programs. First we’ll look at some examples of reading files. package main import ( "bufio" "fmt" "io" "os" "path/filepath" ) Reading files requires checking most calls for errors. This helper

gobyexample.com