用R中的tempfile()创建的临时文件会怎样?

use*_*745 8 r temporary-files

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

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

如果文件被自动删除,会在什么基础上发生(例如R会话结束,关闭RStudio之后,一定时间间隔后或其他时间)?

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

Hug*_*ugh 12

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

tl;drR_CleanTempDir运行时删除临时文件(如 R 会话终止时)

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

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

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

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

在某些情况下tempdir()可能会在长时间运行的 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*/
}
Run Code Online (Sandbox Code Playgroud)

调用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] = '\0';
    }
    exit(status);
}
Run Code Online (Sandbox Code Playgroud)