func RecompressGZip(path string, fo os.FileInfo) error { file, err := os.Open(path) if err != nil { return err } defer file.Close() gzipReader, err := gzip.NewReader(file) if err != nil { return err } defer gzipReader.Close() data, err := ioutil.ReadAll(gzipReader) if err != nil { return err } output, err := os.OpenFile(path+".tmp", os.O_CREATE|os.O_WRONLY, fo.Mode()) if err != nil { return nil } options := zopfli.DefaultOptions() err = zopfli.GzipCompress(&options, data, output) if err != nil { output.Close() os.Remove(path + ".tmp") return err } output.Close() err = os.Rename(path+".tmp", path) return err }
func main() { options := zopfli.DefaultOptions() flag.BoolVar(&options.Verbose, "v", options.Verbose, "verbose mode") flag.BoolVar(&options.VerboseMore, "vv", options.VerboseMore, "more verbose mode") outputToStdout := flag.Bool("c", false, "write the result on standard output, instead of disk") deflate := flag.Bool("deflate", false, "output to deflate format instead of gzip") zlib := flag.Bool("zlib", false, "output to zlib format instead of gzip") gzip := flag.Bool("gzip", true, "output to gzip format") flag.BoolVar(&options.BlockSplittingLast, "splitlast", options.BlockSplittingLast, "do block splitting last instead of first") flag.IntVar(&options.NumIterations, "i", options.NumIterations, "perform # iterations (default 15). More gives more compression but is slower. Examples: -i=10, -i=50, -i=1000") var cpuProfile string flag.StringVar(&cpuProfile, "cpuprofile", "", "write cpu profile to file") flag.BoolVar(¶llel, "parallel", false, "compress in parallel (gzip only); use GOMAXPROCS to set the amount of parallelism. More parallelism = smaller independent chunks, thus worse compression ratio.") flag.Parse() if parallel && !*gzip { fmt.Fprintf(os.Stderr, "Error: parallel is only supported with gzip containers.") return } if options.VerboseMore { options.Verbose = true } var outputType int if *deflate && !*zlib && !*gzip { outputType = zopfli.FORMAT_DEFLATE } else if *zlib && !*deflate && !*gzip { outputType = zopfli.FORMAT_ZLIB } else { outputType = zopfli.FORMAT_GZIP } if options.NumIterations < 1 { fmt.Fprintf(os.Stderr, "Error: must have 1 or more iterations") return } var allFileNames []string if *outputToStdout { allFileNames = append(allFileNames, "") } else { allFileNames = flag.Args() } if len(allFileNames) <= 0 { fmt.Fprintf(os.Stderr, "Please provide filename\n") } if cpuProfile != "" { f, err := os.Create(cpuProfile) if err == nil { pprof.StartCPUProfile(f) defer f.Close() defer pprof.StopCPUProfile() } } for _, fileName := range allFileNames { var outFileName string if *outputToStdout { outFileName = "" } else { switch outputType { case zopfli.FORMAT_GZIP: outFileName = fileName + ".gz" case zopfli.FORMAT_ZLIB: outFileName = fileName + ".zlib" case zopfli.FORMAT_DEFLATE: outFileName = fileName + ".deflate" default: panic("Unknown output type") } if options.Verbose { fmt.Fprintf(os.Stderr, "Saving to: %s\n", outFileName) } } compressErr := compressFile(&options, outputType, fileName, outFileName) if compressErr != nil { fmt.Fprintf(os.Stderr, "could not compress %s: %v\n", fileName, compressErr) } } }