Go 언어 파일 입출력 정리: os, bufio, ioutil 패키지 완벽 가이드

Go에서 파일을 읽고 쓰는 방법은 크게 세 가지 패키지로 나눌 수 있다. 각 패키지의 특징과 사용법을 예제 코드와 함께 살펴보겠다.

1. os 패키지

가장 기본적인 파일 입출력 기능을 제공한다.

파일 쓰기: Write() / WriteString()

package main

import (
    "fmt"
    "os"
)

func main() {
    data := "# Todo List\r\n- 운동하기\r\n- 책 읽기\r\n- 코딩 연습"
    filePath := "todo.md"
    if err := saveToFile(filePath, data); err != nil {
        fmt.Printf("파일 쓰기 실패: %v\n", err)
    }
}

func saveToFile(path, content string) error {
    file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
    if err != nil {
        return err
    }
    defer file.Close()

    _, err = file.WriteString(content)
    if err != nil {
        return err
    }

    // 또는 바이트 슬라이스로 쓰기
    // _, err = file.Write([]byte(content))
    return nil
}

파일 읽기: Read()

package main

import (
    "fmt"
    "os"
)

func main() {
    filePath := "todo.md"
    if err := loadFromFile(filePath); err != nil {
        fmt.Printf("파일 읽기 실패: %v\n", err)
    }
}

func loadFromFile(path string) error {
    file, err := os.Open(path)
    if err != nil {
        return err
    }
    defer file.Close()

    buffer := make([]byte, 1024)
    n, err := file.Read(buffer)
    if err != nil {
        return err
    }

    fmt.Printf("읽은 내용:\n%s", buffer[:n])
    return nil
}

2. bufio 패키지

버퍼링된 입출력을 지원하여 대용량 파일 처리에 효율적이다.

파일 쓰기: WriteString() + Flush()

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    data := "# 회의록\r\n- 프로젝트 계획 수립\r\n- 리소스 할당 논의\r\n- 일정 조정"
    filePath := "meeting.md"
    if err := saveBuffered(filePath, data); err != nil {
        fmt.Printf("버퍼 쓰기 실패: %v\n", err)
    }
}

func saveBuffered(path, content string) error {
    file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
    if err != nil {
        return err
    }
    defer file.Close()

    writer := bufio.NewWriter(file)
    _, err = writer.WriteString(content)
    if err != nil {
        return err
    }

    // 버퍼의 내용을 실제 파일로 플러시
    if err = writer.Flush(); err != nil {
        return err
    }
    return nil
}

파일 읽기: ReadLine()

package main

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

func main() {
    filePath := "meeting.md"
    if err := readLineByLine(filePath); err != nil {
        fmt.Printf("라인 읽기 실패: %v\n", err)
    }
}

func readLineByLine(path string) error {
    file, err := os.OpenFile(path, os.O_RDONLY, 0644)
    if err != nil {
        return err
    }
    defer file.Close()

    reader := bufio.NewReader(file)
    for {
        line, _, err := reader.ReadLine()
        if err == io.EOF {
            break
        }
        if err != nil {
            return err
        }
        fmt.Println(string(line))
    }
    return nil
}

3. ioutil 패키지

가장 간편하게 파일을 읽고 쓸 수 있는 방법을 제공한다. (Go 1.16부터는 os 패키지로 대체 권장)

파일 쓰기: WriteFile()

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    data := "# 설정 파일\r\n- DB_HOST=localhost\r\n- DB_PORT=5432\r\n- DEBUG=true"
    filePath := "config.md"
    if err := saveQuick(filePath, data); err != nil {
        fmt.Printf("빠른 쓰기 실패: %v\n", err)
    }
}

func saveQuick(path, content string) error {
    err := ioutil.WriteFile(path, []byte(content), 0644)
    if err != nil {
        return err
    }
    return nil
}

파일 읽기: ReadFile()

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    filePath := "config.md"
    if err := loadQuick(filePath); err != nil {
        fmt.Printf("빠른 읽기 실패: %v\n", err)
    }
}

func loadQuick(path string) error {
    data, err := ioutil.ReadFile(path)
    if err != nil {
        return err
    }
    fmt.Printf("파일 내용:\n%s", data)
    return nil
}

실행 결과 예시

# Todo List
- 운동하기
- 책 읽기
- 코딩 연습

패키지 선택 가이드

  • os 패키지: 간단한 파일 작업에 적합
  • bufio 패키지: 대용량 파일이나 라인 단위 처리 필요 시
  • ioutil 패키지: 가장 간결한 코드로 파일 전체 읽기/쓰기 가능

태그: go os bufio ioutil 파일입출력

6월 11일 18:58에 게시됨