在 R 中使用 tempfile() 创建的临时文件会怎样?
What happens to tempfiles created with tempfile() in R?
我在包的函数中使用 tempfile()
,因此用户将创建新文件。我不想留下一团糟。
R 会自动删除在使用 tempfile()
访问的目录中创建的文件,还是必须手动删除这些文件?
如果文件被自动删除,发生这种情况的依据是什么(例如,R 会话结束、关闭 RStudio 后、一段时间间隔后或其他原因?)
显然,使用一些额外的代码(相关post:)删除它们并不难,但如果它们是通过某些现有进程自动处理的,我会避免这种情况。
默认情况下,该函数使用 tempdir()
返回的临时目录,其中 returns 是系统临时目录的路径。所以它是由OS控制的。如果您使用不同的目录,我想您将不得不自己清理它。
(所有这些假设您正在使用 tmpdir
的默认参数并且 TEMP
环境变量已为您的操作系统正常设置。)
tl;dr 每当 R_CleanTempDir
运行时都会删除临时文件(就像 R 会话终止时一样)
通过删除临时目录tempdir()
删除临时文件。这是通过内部函数 R_CleanTempDir
发生的(link 指向 unix 实现)。这可以通过各种实例调用,但最常见的情况是通过 quit
(完整链见下文)。为了回答您的问题,临时文件将在 "normal" 退出 R 会话时被删除。 ("normal"是为了避免在不合时宜的时候停电之类的事情,再加上"suicides"。)
确实在 ?quit
的帮助文件中提到了这一点:
Exactly what happens at termination of an R session depends on the platform and GUI interface in use. A typical sequence is to run .Last() and .Last.sys() (unless runLast is false), to save the workspace if requested (and in most cases also to save the session history: see savehistory), then run any finalizers (see reg.finalizer) that have been set to be run on exit, close all open graphics devices, remove the session temporary directory and print any remaining warnings (e.g., from .Last() and device closure).
按照该帮助文件中的建议,您可能想看看 reg.finalizer
是否对您的问题有帮助。
在某些情况下 tempdir()
may be deleted during long-running R session,但要保证删除临时文件,您必须在会话中明确删除它们或退出会话。
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_CleanUp
调用 R_CleanTempDir
:
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] = '[=11=]';
}
exit(status);
}
我在包的函数中使用 tempfile()
,因此用户将创建新文件。我不想留下一团糟。
R 会自动删除在使用 tempfile()
访问的目录中创建的文件,还是必须手动删除这些文件?
如果文件被自动删除,发生这种情况的依据是什么(例如,R 会话结束、关闭 RStudio 后、一段时间间隔后或其他原因?)
显然,使用一些额外的代码(相关post:
默认情况下,该函数使用 tempdir()
返回的临时目录,其中 returns 是系统临时目录的路径。所以它是由OS控制的。如果您使用不同的目录,我想您将不得不自己清理它。
(所有这些假设您正在使用 tmpdir
的默认参数并且 TEMP
环境变量已为您的操作系统正常设置。)
tl;dr 每当 R_CleanTempDir
运行时都会删除临时文件(就像 R 会话终止时一样)
通过删除临时目录tempdir()
删除临时文件。这是通过内部函数 R_CleanTempDir
发生的(link 指向 unix 实现)。这可以通过各种实例调用,但最常见的情况是通过 quit
(完整链见下文)。为了回答您的问题,临时文件将在 "normal" 退出 R 会话时被删除。 ("normal"是为了避免在不合时宜的时候停电之类的事情,再加上"suicides"。)
确实在 ?quit
的帮助文件中提到了这一点:
Exactly what happens at termination of an R session depends on the platform and GUI interface in use. A typical sequence is to run .Last() and .Last.sys() (unless runLast is false), to save the workspace if requested (and in most cases also to save the session history: see savehistory), then run any finalizers (see reg.finalizer) that have been set to be run on exit, close all open graphics devices, remove the session temporary directory and print any remaining warnings (e.g., from .Last() and device closure).
按照该帮助文件中的建议,您可能想看看 reg.finalizer
是否对您的问题有帮助。
在某些情况下 tempdir()
may be deleted during long-running R session,但要保证删除临时文件,您必须在会话中明确删除它们或退出会话。
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_CleanUp
调用 R_CleanTempDir
:
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] = '[=11=]';
}
exit(status);
}