# Cross-platform unpacking of tar archive

**URL:** https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459
**Category:** General Usage
**Created:** [November 24, 2019, 7:37pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459 "2019-11-24T19:37:08Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)
#### Post date: [November 24, 2019, 7:37pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/1 "2019-11-24T19:37:08Z")

</div>

I need to unpack uncompressed .tar archives from within Julia and have it work on all platforms.

Maybe a clue: there seems to be some code for this [here](https://github.com/JuliaLang/Pkg.jl/blob/master/src/PlatformEngines.jl#L720) within `Pkg.PlatformEngines` but I couldn’t figure out how to access it.

Or is there some other way? [Here’s a small demo archive](http://s000.tinyupload.com/index.php?file_id=70309190343224723229) with 3 pages from the Julia docs (117 kB).

---

<div class="post-metadata">

### Author: ![aaowens](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aaowens/32/12101_2.png) [@aaowens](https://discourse.julialang.org/u/aaowens)
#### Post date: [November 24, 2019, 7:59pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/2 "2019-11-24T19:59:54Z")

</div>

There’s a function in DataDeps I’ve used which does this [https://github.com/oxinabox/DataDeps.jl/blob/master/src/post\_fetch\_helpers.jl](https://github.com/oxinabox/DataDeps.jl/blob/master/src/post_fetch_helpers.jl)

I use it in my package here for a zip file: [https://github.com/aaowens/PSID.jl/blob/e4115cd0cd9cc0afc7fad1e64d82c808dd64e756/src/unzip\_data.jl#L66](https://github.com/aaowens/PSID.jl/blob/e4115cd0cd9cc0afc7fad1e64d82c808dd64e756/src/unzip_data.jl#L66)

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [November 24, 2019, 8:05pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/3 "2019-11-24T20:05:57Z")

</div>

There is [a pull request](https://github.com/JuliaLang/julia/pull/33797) to make [JuliaLang/Tar.jl](https://github.com/JuliaLang/Tar.jl) a standard library. That package is new and not registered, but it sounds like it does what you want.

---

<div class="post-metadata">

### Author: ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)
#### Post date: [November 24, 2019, 8:08pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/4 "2019-11-24T20:08:38Z")

</div>

> [@aaowens](#):
>
> There’s a function in DataDeps I’ve used which does this [https://github.com/oxinabox/DataDeps.jl/blob/master/src/post\_fetch\_helpers.jl](https://github.com/oxinabox/DataDeps.jl/blob/master/src/post_fetch_helpers.jl)

Works perfectly on my Windows 10 system, thanks! I’ll try it on a Linux box and a Mac tomorrow.

---

<div class="post-metadata">

### Author: ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)
#### Post date: [November 24, 2019, 8:10pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/5 "2019-11-24T20:10:01Z")

</div>

> [@ericphanson](#):
>
> There is [a pull request](https://github.com/JuliaLang/julia/pull/33797) to make [JuliaLang/Tar.jl](https://github.com/JuliaLang/Tar.jl) a standard library. That package is new and not registered, but it sounds like it does what you want.

Thanks for reminding me. I found that too, but it didn’t work for me because it currently requires Julia 1.4.

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [November 24, 2019, 8:11pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/6 "2019-11-24T20:11:04Z")

</div>

Ah, I didn’t notice that, good point.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [November 24, 2019, 8:26pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/7 "2019-11-24T20:26:26Z")

</div>

The function in DataDeps was originally from BinDeps.jl  
(Or at least based on that)

It should work cross platform.

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [November 24, 2019, 8:45pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/8 "2019-11-24T20:45:06Z")

</div>

The tar format isn’t all that complicated and if you don’t care about various file metadata and just want the filenames and their contents, this quick and dirty hack should be good enough:

```julia
unpack_tar(filename::AbstractString) = open(load_tar, filename, "r")

function unpack_tar(file)
    unpacked_files = Dict{String, String}()

    while true
        record_start = position(file)
        filename = first(split(String(read(file, 100)), "\0"))
        isempty(filename) && break
        seek(file, record_start + 124)
        size = parse(Int, String(read(file, 11)), base = 8)
        seek(file, record_start + 512)
        unpacked_files[filename] = String(read(file, size))
        pos = position(file)
        seek(file, pos + mod(-pos, 512))
    end

    return unpacked_files
end

```

As a bonus, here’s a pure Julia solution for gzip compressed tar files:

```julia
using Inflate

unpack_tar_gz(filename) = unpack_tar(IOBuffer(inflate_gzip(filename)))

```

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [December 5, 2019, 1:34pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/9 "2019-12-05T13:34:05Z")

</div>

Tar.jl has been updated to support Julia 1.3 and now has CI setup for all the usual platforms (including Windows). It is still not registered, however, because we’re trying to figure out if it should be:

1. A standard library
2. A registered public package
3. A private submodule of Pkg
4. Both 2 & 3 with 3 being a vendored snapshot of 2.

But I consider the API to be stable and it’s pretty well tested (93% coverage!). Perhaps I should just register it and then we can vendor a snapshot whenever Pkg needs it.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [December 5, 2019, 4:55pm UTC](https://discourse.julialang.org/t/cross-platform-unpacking-of-tar-archive/31459/10 "2019-12-05T16:55:17Z")

</div>

I’ve opened a pull request to register Tar.jl v1.0.0:

[https://github.com/JuliaRegistries/General/pull/6286](https://github.com/JuliaRegistries/General/pull/6286)

This will go through the usual 3-day waiting period, giving people a chance to chime in on the name and whatever else they might care to chime in on.
