У меня есть несколько ZIP-архивов, каждый из которых содержит несколько текстовых файлов.Я хочу прочитать весь текст в память, по одной строке на файл, и каждый файл помечается соответствующим именем файла, но без удаления исходных файлов ZIP или записи всего содержимого на диск.(Если запись временных файлов является обязательной, их следует удалить после того, как мы закончим их читать или если обработка прервана.)
Например, предположим, что вы создаете простой ZIP-файл, подобный этому:
$ echo 'contents1' > file1
$ echo 'contents2' > file2
$ zip files.zip file1 file2
Затем вызов myfunction("files.zip")
должен вернуть то же самое, что и list(file1 = "contents1\n", file2 = "contents2\n")
.
В настоящее время я использую следующую функцию, которая использует Info-ZIP unzip
.Он работает нормально, за исключением того, что его код, определяющий конец одного файла и начало другого, может сработать вместо содержимого файла.
library(stringr)
slurp.zip = function(path)
# Extracts each file in the zip file at `path` as a single
# string. The names of the resulting list are set to the inner
# file names.
{lines = system2("unzip", c("-c", path), stdout = T)
is.sep = str_detect(lines, "^ (?: inflating|extracting): ")
chunks = lapply(
split(lines[!is.sep], cumsum(is.sep)[!is.sep])[-1],
function(chunk) paste(chunk, collapse = "\n"))
fnames = str_match(lines[is.sep], "^ (?: inflating|extracting): (.+) $")
stopifnot(!anyNA(fnames))
names(chunks) = fnames[,2]
chunks}