package main import ( "bytes" "crypto/rand" "flag" "fmt" "io" mathrand "math/rand" "os" "sync" "time" ) var ( fsize int64 count int64 path string chunk int64 ) func main() { flag.Int64Var(&fsize, "fsizemb", 1, "file size mb") flag.Int64Var(&chunk, "readsizekb", 4, "read chunk size kb") flag.Int64Var(&count, "count", 16, "count") flag.StringVar(&path, "path", "/var/www", "path") flag.Parse() fsize = fsize * 1024 * 1024 chunk = chunk * 1024 fmt.Printf("fsize: %d\n", fsize) fmt.Printf("chunk: %d\n", chunk) err := os.MkdirAll(path+"/files", 0755) if err != nil { panic(err) } wg := new(sync.WaitGroup) for i := int64(0); i < count; i++ { fname := fmt.Sprintf("%s/files/file_%d", path, i) wg.Add(1) go func(i int64) { defer wg.Done() manipulateFile(i, fname) }(i) } wg.Wait() } func manipulateFile(i int64, fname string) { file, err := os.Create(fname) if err != nil { panic(err) } defer file.Close() in := io.LimitReader(rand.Reader, fsize) wrote, err := io.Copy(file, in) if err != nil { panic(err) } fmt.Printf("[%d]: wrote: %s: %d\n", i, fname, wrote) for { time.Sleep(time.Duration(mathrand.Intn(500)+200) * time.Millisecond) offset := mathrand.Int63n(fsize) size := chunk if offset+size > fsize { size = fsize - offset } seeked, err := file.Seek(offset, io.SeekStart) if err != nil { fmt.Printf("[%d]: seek error: %s\n", i, err) continue } fmt.Printf("[%d]: seek offset: %d\n", i, seeked) b := bytes.NewBuffer(make([]byte, 0, size)) read, err := io.Copy(b, io.LimitReader(file, size)) if err != nil { fmt.Printf("[%d]: read error: %s\n", i, err) continue } fmt.Printf("[%d]: read: %d\n", i, read) } }