在 R 中使用 tempfile() 创建的临时文件会发生什么情况?



我在包的函数中使用tempfile(),因此用户将创建新文件。我不想留下一个烂摊子。

R 是自动删除在用tempfile()访问的目录中创建的文件,还是必须手动删除这些文件?

如果文件被自动删除,则在什么基础上发生这种情况(例如,R 会话结束、关闭 RStudio 后、一段时间后或其他原因?

显然,使用一些额外的代码删除它们并不难(相关帖子:https://stackoverflow.com/a/56715074/680068(,但如果它们被一些现有进程自动处理,我会避免这种情况。

(所有这些都假设您使用默认参数来tmpdir并且TEMP环境变量是为您的操作系统正常设置的。

tl;dr 每当R_CleanTempDir运行时(如 R 会话终止时(,都会删除临时文件(

通过删除临时目录tempdir()来删除临时文件。这是通过内部函数R_CleanTempDir(链接到 unix 实现(发生的。这可以通过各种实例调用,但最常见的情况是通过quit(完整链见下文(。为了回答您的问题,临时文件将在 R 会话的"正常"退出下删除。("正常"是为了避免在不合时宜的时候停电,加上"自杀"之类的事情。

事实上,这在?quit的帮助文件中提到了:

R 会话终止时发生的确切情况取决于所使用的平台和 GUI 界面。一个典型的顺序是运行 .最后(( 和 .Last.sys(((除非 runLast 为 false(,以在请求时保存工作区(并且在大多数情况下也保存会话历史记录:请参阅保存历史记录(,然后运行任何已设置为在退出时运行的终结器(参见 reg.finalizer(,关闭所有打开的图形设备,删除会话临时目录并打印任何剩余的警告(例如,来自 .最后((和设备关闭(。

如该帮助文件中的建议,您可能想看看reg.finalizer对您的问题是否有帮助。

在某些情况下,tempdir()可能会在长时间运行的 R 会话期间删除,但若要保证删除临时文件,必须在会话中显式删除它们或退出会话。


do_quit

SEXP attribute_hidden do_quit(SEXP call, SEXP op, SEXP args, SEXP rho)
{
const char *tmp;
SA_TYPE ask=SA_DEFAULT;
int status, runLast;
checkArity(op, args);
/* if there are any browser contexts active don't quit */
if(countContexts(CTXT_BROWSER, 1)) {
warning(_("cannot quit from browser"));
return R_NilValue;
}
if( !isString(CAR(args)) )
error(_("one of "yes", "no", "ask" or "default" expected."));
tmp = CHAR(STRING_ELT(CAR(args), 0)); /* ASCII */
if( !strcmp(tmp, "ask") ) {
ask = SA_SAVEASK;
if(!R_Interactive)
warning(_("save="ask" in non-interactive use: command-line default will be used"));
} else if( !strcmp(tmp, "no") )
ask = SA_NOSAVE;
else if( !strcmp(tmp, "yes") )
ask = SA_SAVE;
else if( !strcmp(tmp, "default") )
ask = SA_DEFAULT;
else
error(_("unrecognized value of 'save'"));
status = asInteger(CADR(args));
if (status == NA_INTEGER) {
warning(_("invalid 'status', 0 assumed"));
status = 0;
}
runLast = asLogical(CADDR(args));
if (runLast == NA_LOGICAL) {
warning(_("invalid 'runLast', FALSE assumed"));
runLast = 0;
}
/* run the .Last function. If it gives an error, will drop back to main
loop. */
R_CleanUp(ask, status, runLast);
exit(0);
/*NOTREACHED*/
}

调用调用R_CleanTempDirR_CleanUp

void R_CleanUp(SA_TYPE saveact, int status, int runLast)
{
if(saveact == SA_DEFAULT) /* The normal case apart from R_Suicide */
saveact = SaveAction;
if(saveact == SA_SAVEASK) {
if(R_Interactive) {
switch (R_YesNoCancel(G_("Save workspace image?"))) {
case YES:
saveact = SA_SAVE;
break;
case NO:
saveact = SA_NOSAVE;
break;
case CANCEL:
// There might be residual events with destroyed handles
R_ProcessEvents();
jump_to_toplevel();
break;
}
} else saveact = SaveAction;
}
switch (saveact) {
case SA_SAVE:
if(runLast) R_dot_Last();
if(R_DirtyImage) R_SaveGlobalEnv();
if (CharacterMode == RGui) {
R_setupHistory(); /* re-read the history size and filename */
wgl_savehistory(R_HistoryFile, R_HistorySize);
} else if(R_Interactive && CharacterMode == RTerm) {
R_setupHistory(); /* re-read the history size and filename */
gl_savehistory(R_HistoryFile, R_HistorySize);
}
break;
case SA_NOSAVE:
if(runLast) R_dot_Last();
break;
case SA_SUICIDE:
default:
break;
}
R_RunExitFinalizers();
editorcleanall();
CleanEd();
KillAllDevices(); /* Unix does not do this under SA_SUICIDE */
AllDevicesKilled = TRUE; /* used in devWindows.c to inhibit callbacks */
R_CleanTempDir(); /* changes directory */
if (R_Interactive && CharacterMode == RTerm)
SetConsoleTitle(oldtitle);
if (R_CollectWarnings && saveact != SA_SUICIDE
&& CharacterMode == RTerm)   /* no point in doing this for Rgui
as the console is about to close */
PrintWarnings();        /* from device close and (if run) .Last */
app_cleanup();
RConsole = NULL;
// Add some protection against calling this more than once:
// caused by signals on Unix, so maybe cannot happen here.
if(ifp) { 
fclose(ifp);    /* input file from -f or --file= */
ifp = NULL; 
}
if(ifile[0]) {
unlink(ifile); /* input file from -e */
ifile[0] = '';
}
exit(status);
}

默认情况下,该函数使用tempdir()返回的临时目录,该目录返回系统临时目录的路径。所以它是由操作系统控制的。如果您使用其他目录,我想您必须自己清理它。

相关内容

最新更新