-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
110 lines (100 loc) · 2.27 KB
/
main.go
File metadata and controls
110 lines (100 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"errors"
"flag"
"fmt"
"io"
"math/rand"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"unicode"
)
const (
myByte = 1 << (10 * iota)
myKilobyte
myMegabyte
myGigabyte
myTerabyte
)
var version = "unknow"
func toBytes(s string) (int64, error) {
s = strings.TrimSpace(s)
s = strings.ToUpper(s)
i := strings.IndexFunc(s, unicode.IsLetter)
if i == -1 {
return strconv.ParseInt(s, 10, 64)
}
bytesString, multiple := s[:i], s[i:]
bytes, err := strconv.ParseFloat(bytesString, 64)
if err != nil || bytes <= 0 {
return 0, errors.New("invalid size")
}
switch multiple {
case "T", "TB":
return int64(bytes * myTerabyte), nil
case "G", "GB":
return int64(bytes * myGigabyte), nil
case "M", "MB":
return int64(bytes * myMegabyte), nil
case "K", "KB":
return int64(bytes * myKilobyte), nil
case "B":
return int64(bytes), nil
default:
return 0, errors.New("invalid size")
}
}
func main() {
num := flag.Uint64("n", 1, "number of files")
size := flag.String("s", "1M", "size(K,M,G,T) of file")
out := flag.String("o", ".", "output dir")
prefix := flag.String("p", "vager", "filename prefix")
threads := flag.Int("t", runtime.NumCPU(), "threads")
ver := flag.Bool("v", false, "show version")
flag.Parse()
if *ver == true {
fmt.Printf("version: %s\n", version)
return
}
fileSize, err := toBytes(*size)
if err != nil {
fmt.Printf("invalid file size: %s, erro:%s", *size, err)
return
}
filePrefix := filepath.Join(*out, fmt.Sprintf("%s-%s", *prefix, *size))
fmt.Printf("gen %d file with size[%s] to %s\n", *num, *size, *out)
var index uint64
wg := sync.WaitGroup{}
for i := 0; i < *threads; i++ {
wg.Add(1)
go func(fileprefix string, n uint64) {
ifd := rand.New(rand.NewSource(time.Now().UnixNano()))
for {
fn := atomic.AddUint64(&index, 1)
if fn > n {
break
}
filename := fmt.Sprintf("%s-%d", fileprefix, fn)
ofd, err := os.Create(filename)
if err != nil {
fmt.Printf("create file %s failed %s\n", filename, err)
break
}
if _, err = io.CopyN(ofd, ifd, fileSize); err != nil {
fmt.Printf("gen random file %s failed %s\n", filename, err)
ofd.Close()
break
}
ofd.Close()
}
wg.Done()
}(filePrefix, *num)
}
wg.Wait()
}