2016-10-28 65 views
1

我想將提取的tar.gz內容複製到go lang中的單個文件。我將只有文件內的文本。將提取的tar.gz複製到單個文件

以下是我目前的代碼。

f, err := os.Open(fullpath) 
if err != nil { 
    log.Panicf("Can not open file %s: %v", fullpath, err) 
    return "" 
} 
defer f.Close() 
reader, err := gzip.NewReader(f) 
if err != nil{ 
    log.Panicf("Cannot read gzip archive %v", err); 
    return "" 
} 
defer reader.Close() 
tar_reader := tar.NewReader(reader) 
var files []io.Reader 
for{ 
    header, err := tar_reader.Next() 
    if err == io.EOF { 
     break 
    } else if err != nil { 
     log.Panicf("Cannot read file inside tarball %v", err); 
     return 0, err 
    } else { 
     log.Println("Parsing file : ", header.Name) 
     files = append(files, tar_reader) 
    } 
} 
reader = io.MultiReader(files...) 
writer, err := os.Create(target) 
if err != nil { 
    log.Panicf("Cannot write unarchived file %v", err); 
    return 0, err 
} 
defer writer.Close() 

result,err := io.Copy(writer, reader) 
if(err != nil) { 
    log.Panicf("Cannot write unarchived file %v", err); 
} 
return result,err 

雖然我沒有收到上述代碼的任何錯誤,但只讀取了文件。輸出沒有數據。請指出我出錯的地方。

回答

2

您將同一個tar.Reader反覆附加到files切片。閱讀標題後,您必須從存檔中讀取文件。在這一點上覆制文件。你可能應該檢查普通文件,對目錄,符號鏈接等。

copied := 0 
for { 
    header, err := tar_reader.Next() 
    if err == io.EOF { 
     break 
    } else if err != nil { 
     log.Fatalf("Cannot read file inside tarball %v", err) 
    } 

    if !(header.Typeflag == tar.TypeReg || header.Typeflag == tar.TypeRegA) { 
     continue 
    } 


    n, err = io.Copy(writer, tar_reader) 
    if err != nil { 
     log.Fatalf("Cannot write unarchived file %v", err) 
    } 
    copied += n 
} 
return copied, nil 
+0

謝謝@JimB,但我想追加所有的tar_readers到一個multireader。那可能嗎? – PiKaY

+0

@PiKaY:不,因爲只有一個tar.Reader。要使用MultiReader,您必須將每個文件複製到單獨的緩衝區以製作單獨的io.Readers。這是做你想要的,但沒有額外的副本。 – JimB

+0

謝謝@JimB由於我當前的代碼組織有一點限制。我想我可以適應這個:)。謝謝你的答案 – PiKaY