第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 golang 中提取壓縮包時缺少文件

在 golang 中提取壓縮包時缺少文件

Go
翻翻過去那場雪 2022-08-15 19:30:11
我正在嘗試這個函數(shù),以便在我解開文件后解壓縮文件,但是,當它解壓縮時,會丟失一些文件夾,我不知道為什么。當我通過GUI打開創(chuàng)建的tarfile時,UnGzip工作正常,因此不包括該功能。func main() {fileUrl := "https://www.clamav.net/downloads/production/clamav-0.103.1.tar.gz"filePath := "clamav-0.103.1.tar.gz"tempFolder := "temp"    err := os.Mkdir(tempFolder, 0755)if err != nil {    panic(err)}err = DownloadFile(filePath, fileUrl)if err != nil {    panic(err)}fmt.Println("Downloaded: " + fileUrl)UnGzip(filePath,tempFolder + "/clamav.tar")UnTar(tempFolder + "/clamav.tar",tempFolder + "/clamAV/")//err := os.RemoveAll("tempFolder")//if err != nil {    //panic(err)//}}func UnTar(tarball, target string) error {reader, err := os.Open(tarball)if err != nil {    return err}defer reader.Close()tarReader := tar.NewReader(reader)for {    header, err := tarReader.Next()    if err == io.EOF {        break    } else if err != nil {        return err    }    path := filepath.Join(target, header.Name)    info := header.FileInfo()    if info.IsDir() {        if err = os.MkdirAll(path, info.Mode()); err != nil {            return err        }        continue    }    file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())    if err != nil {        return err    }    defer file.Close()    _, err = io.Copy(file, tarReader)    if err != nil {        return err    }}return nil}這是我應(yīng)該得到的:想要的,這是我擁有的:有
查看完整描述

3 回答

?
慕田峪9158850

TA貢獻1794條經(jīng)驗 獲得超7個贊

下面是一些示例代碼:


package main


import (

   "archive/tar"

   "compress/gzip"

   "io"

   "os"

   "path"

)


func extract(source string) error {

   file, err := os.Open(source)

   if err != nil { return err }

   defer file.Close()

   gzRead, err := gzip.NewReader(file)

   if err != nil { return err }

   defer gzRead.Close()

   tarRead := tar.NewReader(gzRead)

   for {

      cur, err := tarRead.Next()

      if err == io.EOF { break } else if err != nil { return err }

      os.MkdirAll(path.Dir(cur.Name), os.ModeDir)

      switch cur.Typeflag {

      case tar.TypeReg:

         create, err := os.Create(cur.Name)

         if err != nil { return err }

         defer create.Close()

         create.ReadFrom(tarRead)

      case tar.TypeLink:

         os.Link(cur.Linkname, cur.Name)

      }

   }

   return nil

}

用法:


package main


func main() {

   extract("clamav-0.103.1.tar.gz")

}


查看完整回答
反對 回復(fù) 2022-08-15
?
Helenr

TA貢獻1780條經(jīng)驗 獲得超4個贊

您可能會遇到每個進程允許的打開文件數(shù)。使用標志運行,我認為默認限制為1024。壓縮包有 2758 個文件。ulimitulimit-aopen files


這是因為在處理 .tarReader


要解決此問題,請在處理它們時關(guān)閉每個文件:


func UnTar(tarball, target string) error {

    reader, err := os.Open(tarball)

    if err != nil {

        return err 

    }   

    defer reader.Close()

    tarReader := tar.NewReader(reader)


    for {

        header, err := tarReader.Next()

        if err == io.EOF {

            break

        } else if err != nil {

            return err 

        }


        path := filepath.Join(target, header.Name)

        info := header.FileInfo()

        if info.IsDir() {

            if err = os.MkdirAll(path, info.Mode()); err != nil {

                return err 

            }

            continue

        }


        err = processOneFile(tarReader, path, info.Mode())

        if err != nil {

            return err 

        }

    }   

    return nil 

}


func processOneFile(tarReader io.Reader, filePath string, fileMode os.FileMode) error {

    file, err := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, fileMode)

    if err != nil {

        return err 

    }   

    defer file.Close() // close error discarded

    _, err = io.Copy(file, tarReader)

    return err 

}



查看完整回答
反對 回復(fù) 2022-08-15
?
守著一只汪

TA貢獻1872條經(jīng)驗 獲得超4個贊

雖然關(guān)于的另一個答案已經(jīng)非常好,但我只想補充兩件事:ulimit

  1. 您可以解壓縮gzip并同時讀取tar文件,而不是在兩者之間創(chuàng)建臨時文件。您還可以直接從URL流式傳輸文件,并在下載時將其提取

  2. 有人可能會創(chuàng)建一個惡意的tar.gz文件,該文件會使您的代碼使用zipslip之類的東西覆蓋重要文件(特別是如果您的程序以root身份運行,有人可以注入一個文件路徑,從而覆蓋該文件,甚至可能編輯crontab文件并以這種方式執(zhí)行代碼?),您應(yīng)該檢查一下../../../../etc/passwd

考慮到這一點,我們可以編寫一個直接從中提取的函數(shù),該函數(shù)還檢查目標目錄之外的任何路徑:io.Reader

// untargz decompresses a gzipped tar stream to the directory specified by target.

// Note that `file` should be closed by the caller

func untargz(file io.Reader, targetDir string) (err error) {

    gz, err := gzip.NewReader(file)

    if err != nil {

        return

    }

    // This does not close file

    defer gz.Close()


    tarReader := tar.NewReader(gz)


    for {

        header, err := tarReader.Next()

        if err == io.EOF {

            break

        } else if err != nil {

            return err

        }


        // This can be dangerous, similar to zipslip

        path := filepath.Join(targetDir, header.Name)


        // Check for ZipSlip. More Info: https://snyk.io/research/zip-slip-vulnerability#go

        if !strings.HasPrefix(path, filepath.Clean(targetDir)+string(os.PathSeparator)) {

            err = fmt.Errorf("%s: illegal file path", path)

            return err

        }


        info := header.FileInfo()

        if info.IsDir() {

            if err = os.MkdirAll(path, info.Mode()); err != nil {

                return err

            }

            continue

        }


        file, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())

        if err != nil {

            return err

        }


        _, err = io.Copy(file, tarReader)

        if err != nil {

            file.Close()

            return err

        }


        err = file.Close()

        if err != nil {

            return err

        }

    }


    return nil

}

考慮一下如果在目錄中的文件之后聲明目錄會發(fā)生什么(因為隨后會失?。部赡軙兴鶐椭?,但此函數(shù)不處理這種情況。os.Create


這個函數(shù)可以用來直接流式傳輸?shù)捷敵瞿夸洠蠈嵳f,我不確定這是否是你想要的:


func main() {

    resp, err := http.Get(`https://www.clamav.net/downloads/production/clamav-0.103.1.tar.gz`)

    if err != nil {

        panic(err)

    }

    defer resp.Body.Close()


    err = untargz(bufio.NewReader(resp.Body), "out")

    if err != nil {

        panic(err)

    }


    println("Done")

}

您可以在此處找到完整文件。


查看完整回答
反對 回復(fù) 2022-08-15
  • 3 回答
  • 0 關(guān)注
  • 202 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號