I am using utils::untar()
with its argument files
to extract a single file.
However, if the file is missing, I get a warning and a non-stopping internal error message.
I could remove the warning using suppressWarnings()
, but how can I remove the error messages?
I'm running R 4.1.3 on Windows 10.
library(glue)
tmp = tempdir()
target = glue("{tmp}/spelling_2.2.tar.gz")
download.file("https://cran.r-project.org/src/contrib/Archive/spelling/spelling_2.2.tar.gz", destfile=target)
untar(target, files="spelling/DESCRIPTION", exdir=glue("{tmp}/extract1_ok"))
list.files(glue("{tmp}/extract1_ok"), recursive=TRUE) |> head()
#> [1] "spelling/DESCRIPTION"
list.dirs(glue("{tmp}/extract1_ok"), recursive=TRUE, full.names=FALSE) |> head()
#> [1] "" "spelling"
untar(target, files="xxx.zzz", exdir=glue("{tmp}/extract1_missing"))
#> tar.exe: xxx.zzz: Not found in archive
#> tar.exe: Error exit delayed from previous errors.
#> Warning in untar(target, files = "xxx.zzz", exdir = glue("{tmp}/extract1_missing")): 'tar.exe -xf
#> "C:\Users\Dan\AppData\Local\Temp\RtmpQ3jdcY/spelling_2.2.tar.gz" -C
#> "C:/Users/Dan/AppData/Local/Temp/RtmpQ3jdcY/extract1_missing" "xxx.zzz"'
#> returned error code 1
list.files(glue("{tmp}/extract1_missing"), recursive=TRUE) |> head()
#> character(0)
list.dirs(glue("{tmp}/extract1_missing"), recursive=TRUE, full.names=FALSE) |> head()
#> [1] ""
The warnings can be suppressed using suppressWarnings()
, but the tar.exe: ...
cannot.
Using tar="internal"
is a solution, but it has the side effect of creating empty dirs, which is somehow unwanted. This function will be called a tremendous lot, so removing those dirs would be a bit slow.
tar="internal"
-> PROBLEM: annoying empty dirs
untar(target, files="spelling/DESCRIPTION", exdir=glue("{tmp}/extract_internal"),
tar="internal")
list.files(glue("{tmp}/extract_internal"), recursive=TRUE) |> head()
#> [1] "spelling/DESCRIPTION"
list.dirs(glue("{tmp}/extract_internal"), recursive=TRUE, full.names=FALSE) |> head()
#> [1] "" "spelling"
#> [3] "spelling/inst" "spelling/inst/templates"
#> [5] "spelling/man" "spelling/R"
Use system
or system2
to run your system tar
, then you will have the options to ignore stderr
:
tmp <- tempdir()
target <- file.path(tmp, "spelling_2.2.tar.gz")
download.file("https://cran.r-project.org/src/contrib/Archive/spelling/spelling_2.2.tar.gz", destfile = target)
exdir <- file.path(tmp, "extract1_ok")
files <- "spelling/DESCRIPTION"
dir.create(exdir, showWarnings = FALSE, recursive = TRUE)
if (system2("tar", c("-xf", target, "-C", exdir, files), stderr = NULL)) unlink(exdir, recursive = TRUE)
list.files(exdir, recursive = TRUE) |> head()
list.dirs(exdir, recursive = TRUE, full.names = FALSE) |> head()
exdir <- file.path(tmp, "extract1_missing")
files <- "xxx.zzz"
dir.create(exdir, showWarnings = FALSE, recursive = TRUE)
if (system2("tar", c("-xf", target, "-C", exdir, files), stderr = NULL)) unlink(exdir, recursive = TRUE)
list.files(exdir, recursive = TRUE) |> head()
list.dirs(exdir, recursive = TRUE, full.names = FALSE) |> head()
If you View(untar)
, you are going to see that untar
function construct the call to pass to system
to run the system tar
program.