2
大きなファイルを読みながらN秒ごとにさまざまな統計を報告したいと思います。私はティッカーとチャンネルを見つけましたが、バックグラウンドでファイルを読み続けている間に非ブロックにする方法を見つけられません。私はまた、文字列チャネルを作成しようとしましたselect{ case: <-msg}
しかし、プログラムがデッドロックにクラッシュします。適切な方法は何ですか?ティッカーを使用してチャネルを使用してブロックすることなく統計情報を報告するにはどうすればよいですか?
後で、必要な速度と時間を定期レポートに含めることができるように、差分を追加することにします。
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()
}