当函数的工作完成时,停止执行包中的函数

Stop the execution of a function from a package when its job is done

提问人:panman 提问时间:10/31/2023 更新时间:10/31/2023 访问量:83

问:

我知道如何使用 or 停止使用循环的函数。就我而言,我想使用软件包中的函数从网络上的ZIP存档中下载单个文件。存档有多个包含文件的目录,但可以通过将子目录名称添加到文件名中来专门指向所需的文件。因此,例如,要下载文件并在远程ZIP存档中的文件夹中,可以编写:stop()breakarchive_extract()archivebcgarem7.savbcgchlz7.savTIMSS2019_IDB_SPSS_G8/Data

archive_extract(archive = "https://www.iea.nl/sites/default/files/data-repository/TIMSS/TIMSS2019/TIMSS2019_IDB_SPSS_G8.zip",
    dir = "/mnt/docs/,
    files = c("TIMSS2019_IDB_SPSS_G8/Data/bcgarem7.sav",
              "TIMSS2019_IDB_SPSS_G8/Data/bcgchlz7.sav"))

我写了一个简单的函数来使事情更方便:

library(archive)

download.data <- function(remote.zip, local.dir, file.names) {
               archive_extract(archive = remote.zip,
                               dir = local.dir,
                               files = file.names)
}

然后调用它:

download.data(remote.zip = "https://www.iea.nl/sites/default/files/data-repository/TIMSS/TIMSS2019/TIMSS2019_IDB_SPSS_G8.zip",
          local.dir = "/mnt/docs/",
          file.names = c("TIMSS2019_IDB_SPSS_G8/Data/bcgarem7.sav", "TIMSS2019_IDB_SPSS_G8/Data/bcgchlz7.sav"))

这样就可以了,这两个文件几乎是瞬间下载的,因为它们低于 200K。但是,该功能会继续工作七分钟,这是下载整个ZIP文件(近1GB)所需的时间。由于某种原因,它继续工作,就好像它在仅下载了这两个文件后下载了ZIP文件中的所有文件一样。archive_extract()

我想在下载所需文件后停止执行。由于没有循环,因此检查下载文件夹中的文件数 with and using 和 end 执行不起作用。将调用包装在带有调用 to 的条件中也不起作用。list.files()while()breakarchive_extract()stop()

有谁知道如何在这种情况下在仅删除所需的文件后中断功能?

r 中断

评论

1赞 PGSA 10/31/2023
我对它如何有选择地只下载压缩文件的一部分感到困惑 - 您确定这两个文件实际上是首先下载的,具有完整的内容,而不仅仅是作为占位符创建?
0赞 panman 10/31/2023
是的,文件已下载到磁盘上。我可以使用 SPSS 或 PSPP 打开和查看他们的内容。
0赞 MrFlick 10/31/2023
在 R 代码中似乎没有任何可以执行的操作。该函数在 C 语言中实现,大约在这里:github.com/r-lib/archive/blob/main/src/archive_extract.cpp#L165。该代码遍历存档中的所有文件,检查它们是否与您想要的文件匹配。一旦找到您的文件,就不会提前返回。您似乎很幸运,您的文件位于存档的“前面”。如果要更改该行为,则必须向包作者提出问题。
0赞 panman 10/31/2023
感谢您的回复@MrFlick。我暗暗希望不会是这样......我不会说 C 或 C++,否则我早就请求更改了。我确实在 5 月份提交了一个问题并得到了确认,但尚未实施任何更改。我只是对这篇文章不耐烦。我知道开发人员很忙,所以看来我必须等待。顺便说一句,“你似乎很幸运,你的文件在档案的'前面'”是什么意思?

答:

1赞 Allen Luce 10/31/2023 #1

简短的回答是,今天没有很好的方法可以直接从脚本中执行此操作。

archive_extract C++代码的主循环中,您可以看到它读取文件中的每个存档条目,将其与所需文件列表进行匹配并提取匹配的文件。一旦它读取了所有文件,它就会继续做同样的事情,在它现在空的文件名列表中寻找匹配项。

现在,如果有人向该存储库提交拉取请求,并在该值达到文件名计数后退出循环,您将得到您想要的东西。num_extracted

评论

0赞 panman 10/31/2023
非常感谢您的拉取请求。我无法评估做了什么,因为我不会说C++。我希望它能很快合并。
0赞 Allen Luce 11/1/2023
不用担心。我验证了它在测试套件中的少数测试中有效,并从命令行确认,与以前相比,从该存档中存储这两个文件花费的时间非常少。archive_extract
0赞 Allen Luce 11/1/2023
确定。如果您安装了 devtools,您可以自己尝试一下我的更改:require(devtools); install_github("allenluce/archive")
0赞 panman 11/1/2023
我确实安装了它。它工作得很好。这两个文件在不到半秒的时间内下载完毕。非常感谢你,你是最棒的。