前言
最近遇到这么个情况,有朋友特意录制了一段视频给我,想发给我。但是视频一不小心录制的太大了,有6G这么大。发送过来遇到了很大的麻烦。使用网盘的话速度太慢了,不能忍。后来发现了文叔叔这个工具。
后续
这个工具具有不限速,不用安装等特点,很方便,只有有浏览器就可以使用,所以使用手机也可以发送接收文件。但是有个问题是免费版单个文件最大只能4G。
后来尝试了很多工具,例如使用剪映把视频剪成几段,但是因为视频太大了,打开都崩溃。后来试着使用压缩工具压缩,可是压缩完还是很大,大于4G。(发稿时又变成5G了)
无奈之下,只能自己写程序来把大文件分割成小文件,然后再用文叔叔传给我,最后我用程序合并就ok了。所以使用什么写呢?python最简单,但是需要对方安装python解释器,想想就头痛。用java写?之前写过,但是还是要对方安装jdk。所以似乎GO是唯一的选项了。
真的忽然觉得,关键时候,用go真香,来根华子。
附上代码和使用方式
伸手党下载地址
http://www.azhangbaobao.cn:8888/
使用方式
1.拆分: (-f 加要拆分的文件名)
./split_and_merge.exe -f ./azhang.mp4
合并:(可以额外指定文件名 -o 加输出的文件名,默认是azhang.mp4)
./split_and_merge.exe -a merge
上代码
GO代码:
package main
import (
"flag"
"fmt"
"io/ioutil"
"math"
"os"
"path/filepath"
)
const chunkSize = 4000000000
//const chunkSize = 50000000
var (
action string
infile string
outfile string
)
func split(infile string) {
if infile == "" {
panic("请输入正确的文件名")
}
fileInfo, err := os.Stat(infile)
if err != nil {
if os.IsNotExist(err) {
panic("文件不存在")
}
panic(err)
}
num := math.Ceil(float64(fileInfo.Size()) / chunkSize)
fi, err := os.OpenFile(infile, os.O_RDONLY, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("要拆分成%.0f份\n", num)
b := make([]byte, chunkSize)
var i int64 = 1
for ; i <= int64(num); i++ {
fi.Seek((i-1)*chunkSize, 0)
if len(b) > int(fileInfo.Size()-(i-1)*chunkSize) {
b = make([]byte, fileInfo.Size()-(i-1)*chunkSize)
}
fi.Read(b)
ofile := fmt.Sprintf("./%d.part", i)
fmt.Printf("生成%s\n", ofile)
f, err := os.OpenFile(ofile, os.O_CREATE|os.O_WRONLY, os.ModePerm)
if err != nil {
panic(err)
}
f.Write(b)
f.Close()
}
fi.Close()
fmt.Println("拆分完成")
}
func merge(outfile string) {
fii, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm)
if err != nil {
panic(err)
return
}
part_list, err := filepath.Glob("./*.part")
if err != nil {
panic(err)
return
}
fmt.Printf("要把%v份合并成一个文件%s\n", part_list, outfile)
i := 0
for _, v := range part_list {
f, err := os.OpenFile(v, os.O_RDONLY, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
b, err := ioutil.ReadAll(f)
if err != nil {
fmt.Println(err)
return
}
fii.Write(b)
f.Close()
i++
fmt.Printf("合并%d个\n", i)
}
fii.Close()
fmt.Println("合并成功")
}
func main() {
flag.StringVar(&action, "a", "split", "请输入用途:split/merge 默认是split")
flag.StringVar(&infile, "f", "", "请输入文件名")
flag.StringVar(&outfile, "o", "azhang.mp4", "请输入要合并的文件名")
flag.Parse()
if action == "split" {
split(infile)
} else if action == "merge" {
merge(outfile)
} else {
panic("-a只能输入split/merge")
}
}
编译成exe文件
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build src/split_and_merge/split_and_merge.go
使用方式在上面哦