You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在`untar(files="xxx")`指定文件不存在时实现静默输出?

解决Windows下utils::untar()提取不存在文件时的tar.exe错误信息问题

问题概述

在Windows 10的R 4.1.3环境中,使用utils::untar()的files参数提取单个文件时,若目标文件不存在,除了R抛出的警告外,还会输出tar.exe:开头的系统级错误信息。suppressWarnings()仅能消除R的警告,无法屏蔽这类系统输出;而使用tar="internal"参数虽能避免错误信息,但会生成多余的空目录,频繁调用时删除目录会拉低运行效率。

可复现示例

提取存在的文件(正常场景)

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] ""

使用tar="internal"的副作用

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"

解决方案

默认调用的Windows系统tar.exe会将错误信息输出到标准错误流(stderr),我们可以通过重定向stderr到nul来屏蔽这类输出。以下是封装好的自定义函数,兼顾抑制R警告与系统错误输出,同时不会生成多余空目录:

silent_untar <- function(tarfile, files, exdir = ".") {
  # 构造tar命令,将stderr重定向到nul(Windows专属)
  tar_cmd <- glue::glue(
    'tar.exe -xf "{tarfile}" -C "{exdir}" "{files}" 2>nul'
  )
  # 执行命令并抑制R层面的警告
  suppressWarnings(system(tar_cmd, intern = FALSE))
}

函数测试

# 测试提取不存在的文件:无任何输出
silent_untar(target, files="xxx.zzz", exdir=glue("{tmp}/extract_silent"))
list.files(glue("{tmp}/extract_silent"), recursive=TRUE) |> head()
#> character(0)

# 测试提取存在的文件:正常输出结果,无多余目录
silent_untar(target, files="spelling/DESCRIPTION", exdir=glue("{tmp}/extract_silent_ok"))
list.files(glue("{tmp}/extract_silent_ok"), recursive=TRUE) |> head()
#> [1] "spelling/DESCRIPTION"
list.dirs(glue("{tmp}/extract_silent_ok"), recursive=TRUE, full.names=FALSE) |> head()
#> [1] ""         "spelling"

这个方案无需额外删除目录操作,适合高频调用的场景。

内容的提问来源于stack exchange,提问作者Dan Chaltiel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:07:42