Skip to content

Instantly share code, notes, and snippets.

@serverwentdown
Created December 2, 2017 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save serverwentdown/03d4a2ff23896193c9856da04bf36a94 to your computer and use it in GitHub Desktop.
Save serverwentdown/03d4a2ff23896193c9856da04bf36a94 to your computer and use it in GitHub Desktop.
A simple tool to split files into chunks.
package main
import (
"fmt"
"text/template"
"bytes"
"io"
"os"
"github.com/c2h5oh/datasize"
"gopkg.in/urfave/cli.v2"
)
type Properties struct {
InFile string
N int
NN string
NNN string
NNNN string
}
func main() {
app := &cli.App{
Version: "v1.0.0",
Name: "split",
Usage: "split files by size",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "bytes",
Aliases: []string{"b"},
Usage: "put `SIZE` bytes per output file",
},
},
ArgsUsage: "FILE TEMPLATE",
Action: func(c *cli.Context) error {
inFile := c.Args().Get(0)
outTmpl, err := template.New("tmpl").Parse(c.Args().Get(1))
if c.NArg() < 2 {
cli.ShowAppHelpAndExit(c, 1)
}
if err != nil {
return cli.Exit("template is invalid: " + err.Error(), 1)
}
var size datasize.ByteSize
err = size.UnmarshalText([]byte(c.String("bytes")))
if err != nil || size < 1 {
cli.ShowAppHelpAndExit(c, 1)
}
// Open file to be split
in, err := os.Open(inFile)
defer in.Close()
if err != nil {
return cli.Exit("file " + inFile + " not found", 1)
}
n := 0
for {
prop := Properties{
InFile: inFile,
N: n,
NN: fmt.Sprintf("%02d", n),
NNN: fmt.Sprintf("%03d", n),
NNNN: fmt.Sprintf("%04d", n),
}
var tmplBuf bytes.Buffer
outTmpl.Execute(&tmplBuf, prop)
outFile := tmplBuf.String()
// Check for existing output file
if _, err := os.Stat(outFile); !os.IsNotExist(err) {
return cli.Exit("file " + outFile + " exists", 1)
}
// Create output file
out, err := os.Create(outFile)
if err != nil {
return cli.Exit("file " + outFile + " cannot be created", 1)
}
// Copy size bytes to output file
written, err := io.CopyN(out, in, int64(size.Bytes()))
if err == io.EOF {
fmt.Printf("%d bytes written to last file\n", written)
break
}
if err != nil {
return cli.Exit("an error occurred when writing: " + err.Error(), 1)
}
out.Close()
n++
}
return nil
},
}
app.Run(os.Args)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment