2017-11-11 34 views
2

대용량 파일을 읽는 동안 N 초마다 다양한 통계를보고하고 싶습니다. 티커와 채널을 발견했지만 백그라운드에서 파일을 계속 읽는 동안 비 차단으로 만드는 방법을 알아낼 수 없습니다. 나는 또한 문자열 채널을 만들고 select{ case: <-msg}을 사용하려고 시도했지만 프로그램이 교착 상태에 빠졌다. 적절한 방법은 무엇입니까?채널을 사용하여 차단하지 않고 티커로 통계를보고하는 방법은 무엇입니까?

나중에 diff를 추가하여 필요한 속도와 시간을 정기적 보고서에 포함 할 수 있습니다.

package main 

import (
    "log" 
    "os" 
    "fmt" 
    "bufio" 
    "strings" 
    "time" 
) 

func main() { 
    filename := "large-file.dat" 

    log.Printf("Opening file: '%v'", filename) 
    file, err := os.Open(filename) 
    if err != nil { 
     fmt.Fprintf(os.Stderr, "File error: %v", err) 
     os.Exit(1) 
    } 

    sourceTotalSizeBytes := uint64(0) 
    sourceReadedBytes := uint64(0) 

    if finfo, err := file.Stat(); err == nil { 
     sourceTotalSizeBytes = uint64(finfo.Size()) 
     log.Printf("Size: %v bytes", sourceTotalSizeBytes) 
    } 

    scanner := bufio.NewScanner(file) 

    // Output stats every n seconds 
    ticker := time.NewTicker(time.Second * 2) 
    defer ticker.Stop() 

    for scanner.Scan() { 
     lineReader := strings.NewReader(scanner.Text()) 
     sourceReadedBytes += uint64(lineReader.Size()) 

     // Report stats every n seconds 
     <-ticker.C 
     go func() { 
      percent := (float64(sourceReadedBytes) * float64(100))/float64(sourceTotalSizeBytes) 
      log.Printf("%v/%v %v%%", sourceReadedBytes, sourceTotalSizeBytes, percent) 
     }() 

     // Simulate work being done to line 
     time.Sleep(time.Millisecond * 10) 

    } 

    file.Close() 
} 

답변

2

시세 표시를 막으려면 select를 기본값으로 사용하십시오. 티커에서 값을 받으면 로그합니다.

select { 
case <-ticker.C: 
    percent := (float64(sourceReadedBytes) * float64(100))/float64(sourceTotalSizeBytes) 
    og.Printf("%v/%v %v%%", sourceReadedBytes, sourceTotalSizeBytes, percent) 
default: 
    // do nothing 
}