Created
December 2, 2017 06:32
-
-
Save serverwentdown/03d4a2ff23896193c9856da04bf36a94 to your computer and use it in GitHub Desktop.
A simple tool to split files into chunks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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