golang 小文件写入测试程序

最近总是怀疑磁盘有问题,所以写了一个小程序,测试磁盘写入程序

package main

import (
	"fmt"
	"io/ioutil"
	//	"log"
	"os"
	"runtime"
	"strconv"
	"time"

	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
)

var (
	limitChan chan bool
	t         = time.Tick(time.Second)
	org_path  string
)

type MyMainWindow struct {
	*walk.MainWindow
	edit           *walk.TextEdit
	bnt_selectFile *walk.PushButton
	bnt_start      *walk.PushButton
	path           string
	sbi_gonum      *walk.StatusBarItem
	sbi_status     *walk.StatusBarItem
	file_number    *walk.LineEdit
	go_number      *walk.LineEdit
}

func (mw *MyMainWindow) bnt_selectFile_action() {

	dlg := new(walk.FileDialog)
	dlg.FilePath = mw.path
	dlg.Title = "请选择配置目录..."
	//dlg.Filter = "配置文件 (*.ini)|*.ini|所有文件 (*.*)|*.*"

	if ok, err := dlg.ShowBrowseFolder(mw); err != nil {
		//mw.edit.AppendText("Error : File Open\r\n")
		walk.MsgBox(mw, "出错了", "请选择配置目录", walk.MsgBoxIconError)
		return
	} else if !ok {
		//mw.edit.AppendText("Cancel\r\n")
		return
	}
	//mw.edit.SetText("")
	mw.path = dlg.FilePath
	org_path = mw.path //防止目录不断重复加深
	mw.sbi_status.SetText("写入目录:" + mw.path)
}
func (mw *MyMainWindow) bnt_start_action() {

	if len(mw.path) == 0 {
		//walk.MsgBox(mw, "出错了", "请选择目录", walk.MsgBoxIconError)
		mw.path = "./testdir"
		//return
	} else {
		mw.path = mw.path + "/testdir"
	}
	mw.sbi_status.SetText("写入目录:" + mw.path)
	go dotest(mw)

}

func write_file(path string, data []byte) {
	err := ioutil.WriteFile(path, data, os.ModeAppend)
	if err != nil {
		//log.Print("write file error:", err.Error())
	}
	defer func() {
		<-limitChan //释放队列
	}()
}
func show_goroutine(mw *MyMainWindow) {
	go func() {
		for {
			select {
			case <-t:
				//每秒打印一次goroutine数量
				mw.sbi_gonum.SetText(fmt.Sprintf("NumGoroutine: %d", runtime.NumGoroutine()))
			}
		}
	}()
}
func dotest(mw *MyMainWindow) {

	path := mw.path
	number, _ := strconv.Atoi(mw.file_number.Text())
	ChanNum, _ := strconv.Atoi(mw.go_number.Text())

	limitChan = make(chan bool, ChanNum)
	filecount := []byte(mw.edit.Text())
	if len(filecount) == 0 {
		walk.MsgBox(mw, "出错了", "内容不能为空", walk.MsgBoxIconError)
		return
	}

	mw.bnt_selectFile.SetEnabled(false)
	mw.bnt_start.SetEnabled(false)

	file_len := float32(len(filecount))
	util_mb := float32(1024 * 1024)
	//log.Printf("template lengh:%f mb", file_len/util_mb)

	_, err := os.Stat(path)
	if err != nil {
		os.MkdirAll(path, os.ModePerm)
	}

	t1 := time.Now().UnixNano()

	var size float32 = 0.00
	for i := 1; i < number; i++ {
		size += file_len
		//ioutil.WriteFile(, filecount, os.ModeAppend)
		limitChan <- true
		go write_file(fmt.Sprintf("%s/%d.txt", path, i), filecount)
	}
	t2 := time.Now().UnixNano()
	t_size := size / util_mb
	t_ms := (t2 - t1) / 1e6
	t_s := (t2 - t1) / 1e9
	if t_s == 0 {
		t_s = 1
	}

	mw.sbi_status.SetText(fmt.Sprintf("内容:%f kb,共写入:%f mb,花费:%d ms,每秒写入%d个文件", file_len/1024, t_size, t_ms, int64(number)/t_s))
	mw.bnt_selectFile.SetEnabled(true)
	mw.bnt_start.SetEnabled(true)
	mw.path = org_path
}
func main() {
	mw := &MyMainWindow{}

	go show_goroutine(mw)

	MW := MainWindow{
		AssignTo: &mw.MainWindow,
		Title:    "文件写入速度测试 v1.0",
		MinSize:  Size{500, 600},
		Size:     Size{500, 600},

		Layout: VBox{},
		Children: []Widget{
			Composite{
				Layout: Grid{Columns: 2},
				Children: []Widget{
					Label{
						Text: "写入文件数量:",
					},
					LineEdit{
						AssignTo: &mw.file_number,
						Text:     "1000",
					},
					Label{
						Text: "线程数量:",
					},
					LineEdit{
						AssignTo: &mw.go_number,
						Text:     "10",
					},
				},
			},
			Composite{
				Layout: Grid{Columns: 1},
				Children: []Widget{
					PushButton{
						AssignTo:  &mw.bnt_selectFile,
						Text:      "选择测试目录...",
						OnClicked: mw.bnt_selectFile_action,
					},
					PushButton{
						AssignTo:  &mw.bnt_start,
						Text:      "开始",
						OnClicked: mw.bnt_start_action,
					},

					TextEdit{
						AssignTo: &mw.edit,
						ReadOnly: false,
						VScroll:  true,
					},
				},
			},
		},
		StatusBarItems: []StatusBarItem{
			StatusBarItem{
				AssignTo: &mw.sbi_gonum,
				//Text:     "准备中...",
				Width: 120,
			},
			StatusBarItem{
				AssignTo: &mw.sbi_status,
				Text:     "准备中...",
				Width:    600,
			},
		},
	}

	if _, err := MW.Run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

}

编译方法请查看
https://github.com/lxn/walk