2016-09-22 2 views
1

tarball의 headerinfo에 디렉토리를 쓰는 방법을 알아 내는데 어려움이 있습니다. 예를 들어 다음과 같은 디렉토리 구조가 있습니다.Golang tarring directory

test [dir] 
-- test1.txt 
    -- subDirA [sub dir] 
     -- test2.txt 

Go 타르 실행 파일을 사용하여 테스트를 수행하면 압축이 풀리고 원래 구조가됩니다. 나는 타르에 타르를 -tvf 할 경우, 목록이 될 것입니다 : 내가 수동 테스트의 -cvf 타르를 할 경우

test/test1.txt 
test/subDirA/test2.txt 

후 타르 -tvf을 수행 목록은 다음과 같습니다

test/ 
test/test1.txt 
test/subDirA/ 
test/subDirA/test2.txt 

Go To Tarring 프로그램에서 수행 할 작업입니다. Go 프로그램에서 tarWriter에 디렉토리를 추가하는 새로운 방법 writeDirToTar을 추가하려고했습니다. fileWalk 함수에서 writeFileToTar 또는 writeDirToTar를 호출합니다. writeDirToTario.Copy(tarWriter, file)을 호출하면 "테스트/subDirA가 디렉토리입니다."라는 오류가 발생합니다. 이 문제를 해결할 수있는 방법이 있습니까?

func writeToTar(fileDir string, 
     sourceBase string, 
     tarWriter *tar.Writer, 
     f os.FileInfo) error { 

     file, err := os.Open(fileDir) 
     if err != nil { 
       log.Print("error opening file") 
       return err 
     } 
     defer file.Close() 

     // relative paths are used to preserve the directory paths in each file path 
     relativePath, err := filepath.Rel(sourceBase, fileDir) 

     tarheader := new(tar.Header) 
     tarheader.Name = relativePath 
     tarheader.Size = f.Size() 
     tarheader.Mode = int64(f.Mode()) 
     tarheader.ModTime = f.ModTime() 

     err = tarWriter.WriteHeader(tarheader) 
     if err != nil { 
       log.Print("error writing tarHeader") 
       return err 
     } 
     _, err = io.Copy(tarWriter, file) 
     if err != nil { 
       log.Print("error writing to tarWriter") 
       return err 
     } 
     return nil 
} 

func writeDirToTar(fileDir string, 
     sourceBase string, 
     tarWriter *tar.Writer, 
     f os.FileInfo) error { 

     file, err := os.Open(fileDir) 
     if err != nil { 
       log.Print("error opening file") 
       return err 
     } 
     defer file.Close() 

     // relative paths are used to preserve the directory paths in each file path 
     relativePath, err := filepath.Rel(sourceBase, fileDir) 

     if tarHeader, err := tar.FileInfoHeader(f, relativePath); err != nil { 
       log.Print("error writing tarHeader") 
       return err 
     } 

     tarHeader.Name = relativePath 
     tarheader.Mode = int64(f.Mode()) 
     tarheader.ModTime = f.ModTime() 

     _, err = io.Copy(tarWriter, file) 
     if err != nil { 
       log.Print("error writing to tarWriter") 
       return err 
     } 
     return nil 

} 

답변

1

당신은 tar.HeaderTypeflag 필드가 누락하고 있습니다.

tarheader := &tar.Header{ 
    Name:  relativePath, 
    Mode:  int64(f.Mode()), 
    ModTime: f.ModTime(), 
    Typeflag: tar.TypeDir, 
} 

당신은 여기에 크기를 원하는 않으며, 내부 디렉토리 데이터 구조는 타르에 아무 의미도 없기 때문에 당신이 디렉토리 데이터를 복사 할하지 않는다 : 적어도 당신이 원하는 것 디렉토리를 들어

.

파일 이름에 /을 추가하여 디렉토리임을 눈으로 확인하고 POSIX 타르 동작과 일치시킬 수도 있습니다.

또는 올바른 헤더 구조를 만들기 위해 파일을 사용한 것처럼 tar.FileInfoHeader 함수를 사용할 수도 있습니다.