Created
December 7, 2009 12:43
-
-
Save Arachnid/250800 to your computer and use it in GitHub Desktop.
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 ( | |
"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