|
|
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
|
|
|
}
|