[Go] 대용량 파일 chunk 단위로 나누기

2022. 7. 21. 02:13·Go
반응형

Go lang으로 대용량 파일 chunk 단위로 나누기

Go lang으로 대용량 파일에 대해서 chunk 단위로 나누어 보자. 나누기 위해서 우선 대용량 파일을 생성한 후 나누기를 진행 할 것이다.

  1. 대용량 파일 생성
  2. 파일 나누기

1. 대용량 파일 생성

package main

import (
    "fmt"
    "math"
    "os"
    "runtime"
    "strconv"
    "time"
)

const MAX_CONCURRENT_JOB = 10
const NUMBER_OF_UNORDERED = 100000000 

const BIG_DATA_ROOT = "data"
const BIG_DATA_FILE_PATH = "data/big_data.txt"

const FILE_CHUNK_SIZE = 10 * (1 << 20) // 10MB = 10 * (1024² = 2²⁰)

func ifNotExistThenMkdir(dir string) {
    if _, err := os.Stat(dir); os.IsNotExist(err) {
        os.Mkdir(dir, 0644)
    }
}

func ifErrorThenPanic(err error) {
    if err != nil {
        panic(err)
    }
}

func createUnorderedFile(number int) {
    // create dir & file
    ifNotExistThenMkdir(BIG_DATA_ROOT)
    file, err := os.Create(BIG_DATA_FILE_PATH)
    ifErrorThenPanic(err)
    defer file.Close()

    // go write
    channel := make(chan bool, MAX_CONCURRENT_JOB)
    for i := 0; i < number; i++ {
        go writeNumber(file, rand.Intn(100), channel)
        <-channel
    }
}

func writeNumber(f *os.File, d int, ch chan bool) {
    // write
    _, err := f.Write([]byte(strconv.Itoa(d) + " "))
    if err != nil {
        ch <- false
    }
    ch <- true
}

파일이 생성 되었다.

2. 파일 나누기

func splitFileToChunks() {
    // create dir & file
    ifNotExistThenMkdir(SPLIT_DATA_ROOT)

    // open file
    readFile, err := os.Open(BIG_DATA_FILE_PATH)
    ifErrorThenPanic(err)
    defer readFile.Close()

    // get info about file
    readFileInfo, err := readFile.Stat()
    ifErrorThenPanic(err)
    readFileSize := readFileInfo.Size()

    // calculate count will be split
    splitCount := int(math.Ceil(float64(readFileSize) / FILE_CHUNK_SIZE))

    // split
    channel := make(chan bool, splitCount)
    for i := 0; i < int(splitCount); i++ {
        go intoChunk(readFile, readFileSize, i, channel)
        <-channel
    }
}

func intoChunk(readFile *os.File, readFileSize int64, i int, ch chan bool) {
    // default size or rest of file size
    chunkSize := int(math.Min(FILE_CHUNK_SIZE, float64(readFileSize-int64(i*FILE_CHUNK_SIZE))))
    buffer := make([]byte, chunkSize)

    // read
    readFile.Read(buffer)
    splitFileName := SPLIT_DATA_FILE_PATH + strconv.Itoa(i+1) + ".txt"

    // create
    splitFile, err := os.Create(splitFileName)
    if err != nil {
        ch <- false
    }
    defer splitFile.Close()

    // write
    _, err = splitFile.Write(buffer)
    if err != nil {
        ch <- false
    }
    ch <- true
}

10MB 단위로 chunk 생성 이후 마지막 파일에서 file size는 rest of file size

Main 함수

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU() / 2)
    start := time.Now()
    // main
    createUnorderedFile(NUMBER_OF_UNORDERED)
    splitFileToChunks()
    fmt.Println("Total Execute Time: " + time.Now().Sub(start).String())
}
728x90
반응형
저작자표시 비영리 변경금지 (새창열림)
'Go' 카테고리의 다른 글
  • [Go] File 정보 확인
  • [Go lang] Excel 읽기, 쓰기
  • [Go] variable type별 printf format
  • Golang
상쾌한기분
상쾌한기분
  • 상쾌한기분
    상쾌한기분
    상쾌한기분
  • 전체
    오늘
    어제
    • 분류 전체보기 (251)
      • Python (44)
        • Python (26)
        • Django (6)
        • Flask (4)
        • Open Source (6)
      • Kotlin & Java (5)
        • Spring (2)
        • 프로젝트 (1)
      • Go (11)
      • Database (24)
        • MySQL (21)
        • Redis (3)
      • Infrastructure (2)
        • CDC (4)
        • Kafka (5)
        • Prometheus (2)
        • Fluentd (11)
        • Docker (1)
        • Airflow (2)
        • VPN (2)
      • IT (26)
        • AI (9)
        • Langchain (8)
        • Web (18)
        • Git (8)
        • 리팩토링 (9)
        • Micro Service Architecture (8)
        • Clean Code (16)
        • Design Pattern (0)
        • 수학 (1)
        • 알고리즘 (14)
      • OS (14)
        • Centos (10)
        • Ubuntu (3)
        • Mac (1)
      • Search Engine (2)
        • ElasticSearch (1)
        • Lucene Solr (1)
      • PHP (2)
        • Laravel (1)
        • Codeigniter (1)
  • 블로그 메뉴

    • Github 방문
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    파이썬
    ollama
    LLM
    티스토리챌린지
    Golang
    Langchain
    fluentd
    python
    오블완
    CDC
    백준
    docker
    http
    performance
    go
    Kafka
    git
    prompt
    Redis
    MYSQL
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
상쾌한기분
[Go] 대용량 파일 chunk 단위로 나누기
상단으로

티스토리툴바