package starcrypto import ( "bufio" "errors" "fmt" "io" "io/ioutil" "math/rand" "os" "path/filepath" "regexp" "strconv" "strings" "time" ) // Attach 合并src与dst文件并输出到output中 func Attach(src, dst, output string) error { fpsrc, err := os.Open(src) if err != nil { return err } defer fpsrc.Close() fpdst, err := os.Open(dst) if err != nil { return err } defer fpdst.Close() fpout, err := os.Create(output) if err != nil { return err } defer fpout.Close() if _, err := io.Copy(fpout, fpsrc); err != nil { return err } for { buf := make([]byte, 1048574) n, err := fpdst.Read(buf) if err != nil { if err == io.EOF { break } return err } fpout.Write(buf[0:n]) } return nil } // Detach 按bytenum字节大小分割src文件到dst1与dst2两个新文件中去 func Detach(src string, bytenum int, dst1, dst2 string) error { fpsrc, err := os.Open(src) if err != nil { return err } defer fpsrc.Close() fpdst1, err := os.Create(dst1) if err != nil { return err } defer fpdst1.Close() fpdst2, err := os.Create(dst2) if err != nil { return err } defer fpdst2.Close() sumall := 0 var buf []byte for { if bytenum-sumall < 1048576 { buf = make([]byte, bytenum-sumall) } else { buf = make([]byte, 1048576) } n, err := fpsrc.Read(buf) if err != nil { return err } sumall += n fpdst1.Write(buf[0:n]) if sumall == bytenum { break } } for { buf = make([]byte, 1048576) n, err := fpsrc.Read(buf) if err != nil { if err == io.EOF { break } return err } fpdst2.Write(buf[0:n]) } return nil } // SplitFile 把src文件按要求分割到dst中去,dst应传入带*号字符串 // 如果bynum=true 则把文件分割成num份 // 如果bynum=false 则把文件按num字节分成多份 func SplitFile(src, dst string, num int, bynum bool, shell func(float64)) error { fpsrc, err := os.Open(src) if err != nil { return err } defer fpsrc.Close() stat, _ := os.Stat(src) filebig := float64(stat.Size()) if bynum { if int(filebig) < num { return errors.New("file is too small to split") } } balance := int(filebig/float64(num)) + 1 if !bynum { balance = num } nownum := 0 fpdst, err := os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1)) if err != nil { return err } defer fpdst.Close() var sum, tsum int = 0, 0 var buf []byte for { if balance-sum < 1048576 { buf = make([]byte, balance-sum) } else { buf = make([]byte, 1048576) } n, err := fpsrc.Read(buf) if err != nil { if err == io.EOF { break } return err } sum += n tsum += n fpdst.Write(buf[0:n]) go shell(float64(tsum) / filebig * 100) if sum == balance { fpdst.Close() nownum++ fpdst, err = os.Create(strings.Replace(dst, "*", fmt.Sprint(nownum), -1)) if err != nil { return err } sum = 0 } } return nil } // MergeFile 合并src文件到dst文件中去,src文件应传入带*号字符串 func MergeFile(src, dst string, shell func(float64)) error { tmp := strings.Replace(src, "*", "0", -1) dir, err := ioutil.ReadDir(filepath.Dir(tmp)) if err != nil { return err } base := filepath.Base(src) tmp = strings.Replace(base, "*", "(\\d+)", -1) reg := regexp.MustCompile(tmp) count := 0 var filebig float64 for _, v := range dir { if reg.MatchString(v.Name()) { count++ filebig += float64(v.Size()) } } fpdst, err := os.Create(dst) defer fpdst.Close() if err != nil { return err } var sum int64 for i := 0; i < count; i++ { fpsrc, err := os.Open(strings.Replace(src, "*", strconv.Itoa(i), -1)) if err != nil { return err } for { buf := make([]byte, 1048576) n, err := fpsrc.Read(buf) if err != nil { if err == io.EOF { break } return err } sum += int64(n) go shell(float64(sum) / filebig * 100) fpdst.Write(buf[0:n]) } fpsrc.Close() } return nil } // FillWithRandom 随机写filesize大小的文件,每次buf大小为bufcap,随机bufnum个字符 func FillWithRandom(filepath string, filesize int, bufcap int, bufnum int, shell func(float64)) error { var buf [][]byte var buftmp []byte rand.Seed(time.Now().Unix()) if bufnum <= 0 { bufnum = 1 } if bufcap > filesize { bufcap = filesize } myfile, err := os.Create(filepath) if err != nil { return err } defer myfile.Close() writer := bufio.NewWriter(myfile) for i := 0; i < bufnum; i++ { buftmp = []byte{} for j := 0; j < bufcap; j++ { buftmp = append(buftmp, byte(rand.Intn(256))) } buf = append(buf, buftmp) } sum := 0 for { if filesize-sum < bufcap { writer.Write(buf[rand.Intn(bufnum)][0 : filesize-sum]) sum += filesize - sum } else { writer.Write(buf[rand.Intn(bufnum)]) sum += bufcap } go shell(float64(sum) / float64(filesize) * 100) if sum >= filesize { break } } writer.Flush() return nil }