有没有大神 知道,go 处理解压, rar格式压缩包的

mannysys · · 1608 次点击
3楼 <a href="/user/mannysys" title="@mannysys">@mannysys</a> ```go package main import ( &#34;fmt&#34; &#34;io&#34; &#34;os&#34; &#34;path/filepath&#34; &#34;runtime&#34; &#34;github.com/mholt/archiver&#34; &#34;github.com/nwaples/rardecode&#34; &#34;github.com/schollz/progressbar&#34; ) func main() { r := archiver.NewRar() count := 0 err := r.Walk(&#34;mytest.rar&#34;, func(f archiver.File) error { if !f.IsDir() { count += 1 } return nil }) if err != nil { panic(err) } fmt.Println(&#34;File count: &#34;, count) bar := progressbar.New(count) destination := &#34;./&#34; err = r.Walk(&#34;mytest.rar&#34;, func(f archiver.File) error { rh, ok := f.Header.(*rardecode.FileHeader) if !ok { return fmt.Errorf(&#34;expected header&#34;) } to := destination + rh.Name if !f.IsDir() &amp;&amp; !r.OverwriteExisting &amp;&amp; fileExists(to) { return fmt.Errorf(&#34;file already exists: %s&#34;, to) } // if files come before their containing folders, then we must // create their folders before writing the file err := mkdir(filepath.Dir(to)) if err != nil { return fmt.Errorf(&#34;making parent directories: %v&#34;, err) } if f.IsDir() { return nil } bar.Add(1) return writeNewFile(to, f.ReadCloser, rh.Mode()) }) if err != nil { panic(err) } } func writeNewFile(fpath string, in io.Reader, fm os.FileMode) error { err := os.MkdirAll(filepath.Dir(fpath), 0755) if err != nil { return fmt.Errorf(&#34;%s: making directory for file: %v&#34;, fpath, err) } out, err := os.Create(fpath) if err != nil { return fmt.Errorf(&#34;%s: creating new file: %v&#34;, fpath, err) } defer out.Close() err = out.Chmod(fm) if err != nil &amp;&amp; runtime.GOOS != &#34;windows&#34; { return fmt.Errorf(&#34;%s: changing file mode: %v&#34;, fpath, err) } _, err = io.Copy(out, in) if err != nil { return fmt.Errorf(&#34;%s: writing file: %v&#34;, fpath, err) } return nil } func fileExists(name string) bool { _, err := os.Stat(name) return !os.IsNotExist(err) } func mkdir(dirPath string) error { err := os.MkdirAll(dirPath, 0755) if err != nil { return fmt.Errorf(&#34;%s: making directory: %v&#34;, dirPath, err) } return nil } ``` 这个库只提供了顺序遍历文件的方式,不完整遍历一遍就不知道到底有多少个文件. 而第一次的遍历获取文件总数的时候会消耗很长时间,暂时没想到什么好办法, 可能需要fork下来,自己改源码
#5
更多评论
可以看看这个 https://github.com/mholt/archiver
#1
一个简单的示例,不过这个库还不支持压缩 ```go package main import ( &#34;fmt&#34; &#34;io/ioutil&#34; &#34;github.com/mholt/archiver&#34; &#34;github.com/nwaples/rardecode&#34; ) func main() { r := archiver.NewRar() err := r.Walk(&#34;mytest.rar&#34;, func(f archiver.File) error { rh, ok := f.Header.(*rardecode.FileHeader) if !ok { return fmt.Errorf(&#34;expected header&#34;) } fmt.Println(&#34;FileName:&#34;, rh.Name) content, err := ioutil.ReadAll(f) if err != nil { return err } fmt.Println(&#34;FileContent:&#34;, string(content)) return nil }) if err != nil { panic(err) } err = r.Unarchive(&#34;mytest.rar&#34;, &#34;mytest&#34;) if err != nil { panic(err) } } ```
#2