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

标签 r temporary-files

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

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

如果文件被自动删除,这种情况发生的依据是什么(例如,R session 结束、关闭 RStudio 后、一段时间间隔后或其他情况?)

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

最佳答案

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

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

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

事实上,?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 ,但为了保证删除临时文件,您必须在 session 中显式删除它们或退出 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] = '\0';
    }
    exit(status);
}

关于r - 在 R 中使用 tempfile() 创建的临时文件会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58095164/

相关文章:

c# - 在内存中创建一个 "directory"?

python 临时文件 : how to open several times the temp file?

r - 使用 .fortran() 编写调用 Fortran 库的 R 包

r - 在 R 中找出 PDF 的编码

python - 为什么 tempfile 在我的 XP 机器上使用 DOS 8.3 目录名称?

python - 尝试用创建的临时文件替换原始文件

R 图形 : axis label placement relative to tick labels?

r - 下拉菜单未在 Shiny 的 tabPanel 中扩展

r - 如何在R中按组删除前导和尾随NA的行

java - 应用程序完成工作后如何删除 ICEpdf 临时文件?