Чтение файлов из архива tar.gz в Nim
Ищите способ чтения файла из архива tar.gz с использованием языка программирования Nim (версия 0.11.2). Скажи у меня есть архив
/my/path/to/archive.tar.gz
и файл в этом архиве
my/path/to/archive/file.txt
Моя цель - прочитать содержимое файла построчно в Nim. В Python я могу сделать это с помощью модуля tarfile. В Nim есть модули libzip и zlib, но документация минимальна и примеров нет. Есть также модуль zipfiles, но я не уверен, что он способен работать с архивами tar.gz.
3 ответа
Насколько мне известно, libzip и zlib нельзя использовать для чтения файлов tar (afaik поддерживает только архивы zip и / или сжатие необработанных строк, в то время как tar.gz требует gzip + tar). К сожалению, похоже, что пока нет библиотек Nim, которые читают архивы tar.gz.
Если ты в порядке с быстрым и грязным tar
решение, вы можете сделать это:
import osproc
proc extractFromTarGz(archive: string, filename: string): string =
# -z extracts
# -f specifies filename
# -z runs through gzip
# -O prints to STDOUT
result = execProcess("tar -zxf " & archive & " " & filename & " -O")
let content = extractFromTarGz("test.tar.gz", "some/subpath.txt")
Если вам нужно чистое и гибкое решение, это хорошая возможность написать оболочку для библиотеки libarchive;).
В проекте моей компании мы использовали следующий модуль, представляющий файлы gzip в виде потоков:
import
zlib, streams
type
GZipStream* = object of StreamObj
f: GzFile
GzipStreamRef* = ref GZipStream
proc fsClose(s: Stream) =
discard gzclose(GZipStreamRef(s).f)
proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int =
return gzread(GZipStreamRef(s).f, buffer, bufLen)
proc fsAtEnd(s: Stream): bool =
return gzeof(GZipStreamRef(s).f) != 0
proc newGZipStream*(f: GzFile): GZipStreamRef =
new result
result.f = f
result.closeImpl = fsClose
result.readDataImpl = fsReadData
result.atEndImpl = fsAtEnd
# other methods are nil!
proc newGZipStream*(filename: cstring): GZipStreamRef =
var gz = gzopen(filename, "r")
if gz != nil: return newGZipStream(gz)
Но вам также необходимо иметь возможность прочитать заголовок tar, чтобы найти правильное местоположение нужного файла в несжатом потоке gzip. Для этого вы можете обернуть какую-нибудь существующую библиотеку C, например libtar, или развернуть собственную реализацию.
Я создал основной untar
пакет, который может помочь с этим: https://github.com/dom96/untar