Skip to content

Instantly share code, notes, and snippets.

@Arachnid
Created December 7, 2009 12:43
Show Gist options
  • Save Arachnid/250800 to your computer and use it in GitHub Desktop.
Save Arachnid/250800 to your computer and use it in GitHub Desktop.
package main
import (
"flag";
"log";
"os";
"strings";
"time";
)
func main() {
var if_f *string = flag.String("if", "", "Input file");
var of *string = flag.String("of", "", "Output file(s)");
var bs *int = flag.Int("bs", 4096, "Block size in bytes");
var statusinterval *int = flag.Int("statusinterval", -1, "Print status every n blocks");
flag.Parse();
of_arg := *of;
if strings.HasSuffix(of_arg, ",") {
of_arg = of_arg[0:len(of_arg)-1];
}
outs := strings.Split(of_arg, ",", -1);
chans := make([]chan []byte, len(outs));
var infile *os.File;
var ok os.Error;
if infile, ok = os.Open(*if_f, os.O_RDONLY, 0644); ok != nil {
log.Exitf("Unable to open input file: %s\n", ok);
}
for i, out := range outs {
chans[i] = make(chan []byte);
if outfile, ok := os.Open(out, os.O_WRONLY | os.O_CREAT, 0644); ok != nil {
log.Exitf("Unable to poen output file %s: %s\n", out, ok);
} else {
go write_blocks(out, outfile, chans[i]);
}
}
total_bytes := 0;
for i := 0; true; i++ {
if *statusinterval > 0 && i % *statusinterval == 0 {
log.Stdoutf("Written %d blocks (%d bytes)\n", i, total_bytes);
}
var size int;
var ok os.Error;
buf := make([]byte, *bs);
// Read a block
switch size, ok = infile.Read(buf); ok {
case os.EOF:
break;
case nil:
default:
log.Exitf("Error reading block: %s\n", ok);
}
total_bytes += size;
if size == 0 {
break;
}
// Take just the read bytes
s := buf[0:size];
// Send it to the channels to be written
for j := 0; j < len(chans); j++ {
chans[j] <- s;
}
}
infile.Close();
// Send empty buffers to all open channels to let them know they should close
for i := 0; i < len(chans); i++ {
chans[i] <- []byte{};
}
time.Sleep(5000000);
}
func write_blocks(outname string, outfile *os.File, in chan []byte) {
for {
block := <-in;
if len(block) > 0 {
if _, err := outfile.Write(block); err != nil {
log.Exitf("Error writing to %s: %s\n", outname, err);
}
} else {
outfile.Close();
return;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment