Skip to content
SP StackPractices
beginner Por StackPractices

Generar Archivos Temporales

Cómo crear archivos y directorios temporales de forma segura con limpieza automática en Python, Node.js, Java y Bash.

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Descripción General

Los archivos temporales son esenciales para almacenar datos intermedios, archivos de subida durante procesamiento o secretos que no deberían persistir en disco. Crearlos incorrectamente puede llevar a vulnerabilidades de seguridad (nombres predecibles), fugas de recursos (archivos nunca eliminados) o incompatibilidad entre plataformas.

Cuándo Usar

  • Almacenar archivos de subida antes de la validación y almacenamiento permanente
  • Mantener datos descifrados o secretos brevemente durante el procesamiento
  • Almacenar en caché resultados intermedios de computación dentro de la vida útil de un proceso
  • Ejecutar tests que necesitan un estado aislado del sistema de archivos
  • Intercambiar datos que no caben en memoria durante procesamiento por batch

Cuándo NO Usar

  • Almacenamiento a largo plazo de datos de usuario — usa rutas permanentes con backups apropiados
  • Datos que deben sobrevivir reinicios de proceso — los directorios temporales pueden ser borrados al reiniciar
  • Secretos altamente sensibles en sistemas compartidos — usa enfoques solo en memoria o volúmenes cifrados
  • Archivos que múltiples procesos necesitan descubrir por nombre — los nombres temporales son aleatorios

Implementación Paso a Paso

Python

import tempfile
import os

# Archivo temporal (auto-eliminado al cerrar)
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=True) as f:
    f.write('{"key": "value"}')
    f.flush()
    print(f"Archivo temp: {f.name}")
    # El archivo se elimina automáticamente al salir del contexto

# Directorio temporal (auto-eliminado con cleanup=True)
with tempfile.TemporaryDirectory() as tmpdir:
    path = os.path.join(tmpdir, 'report.txt')
    with open(path, 'w') as f:
        f.write('Datos temporales del reporte')
    print(f"Dir temp: {tmpdir}")
    # El directorio y todo su contenido se eliminan al salir del contexto

# Limpieza manual (útil cuando pasas la ruta a un proceso externo)
tmp = tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False)
try:
    tmp.write('id,name\n1,Alice\n')
    tmp.close()
    # Pasa tmp.name a herramienta externa...
finally:
    os.unlink(tmp.name)

Node.js

import os from 'os';
import fs from 'fs';
import path from 'path';

// Usando fs promises con limpieza personalizada
async function withTempFile(data, suffix = '.tmp') {
    const tmpPath = path.join(os.tmpdir(), `tmp-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix}`);
    try {
        await fs.promises.writeFile(tmpPath, data);
        return tmpPath;
    } catch (err) {
        await fs.promises.unlink(tmpPath).catch(() => {});
        throw err;
    }
}

// Usando el paquete tmp (recomendado para producción)
import tmp from 'tmp';

// Limpieza automática al salir del proceso
const tmpObj = tmp.fileSync({ postfix: '.json' });
fs.writeFileSync(tmpObj.name, '{"key": "value"}');
// tmpObj.removeCallback() elimina el archivo

const tmpDir = tmp.dirSync({ unsafeCleanup: true });
// Elimina recursivamente el directorio al limpiar

Java

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

// Java 7+ NIO.2 (recomendado)
public class TempFileExample {
    public static void main(String[] args) throws IOException {
        // Crear archivo temp en el directorio temp por defecto
        Path tempFile = Files.createTempFile("prefix-", ".txt");
        System.out.println("Creado: " + tempFile);
        Files.writeString(tempFile, "datos temporales");

        // Crear directorio temp
        Path tempDir = Files.createTempDirectory("myapp-");
        Path nested = tempDir.resolve("nested.txt");
        Files.writeString(nested, "contenido anidado");

        // Registrar para eliminación al salir de la JVM (best effort)
        tempFile.toFile().deleteOnExit();
        tempDir.toFile().deleteOnExit();

        // Limpieza explícita
        Files.deleteIfExists(tempFile);
        Files.walk(tempDir)
            .sorted((a, b) -> -a.compareTo(b))
            .forEach(p -> {
                try { Files.deleteIfExists(p); }
                catch (IOException e) { /* ignorar */ }
            });
    }
}

Bash

#!/bin/bash
set -euo pipefail

# Crear archivo temp (portable, compatible POSIX)
TMPFILE=$(mktemp "${TMPDIR:-/tmp}/XXXXXX.json")
trap 'rm -f "$TMPFILE"' EXIT

echo '{"status": "ok"}' > "$TMPFILE"
# Procesar archivo...
echo "Usando: $TMPFILE"

# Crear directorio temp
TMPDIR_PATH=$(mktemp -d "${TMPDIR:-/tmp}/myapp.XXXXXX")
trap 'rm -rf "$TMPDIR_PATH"' EXIT

# Múltiples recursos temp — usa una función de limpieza
cleanup() {
    rm -f "$TMPFILE" 2>/dev/null || true
    rm -rf "$TMPDIR_PATH" 2>/dev/null || true
}
trap cleanup EXIT

# Avanzado: generar ruta temp única sin crear el archivo
UNIQUE_PATH="${TMPDIR:-/tmp}/batch_$(date +%s)_$$_$RANDOM.csv"

Mejores Prácticas

  • Siempre usa mktemp o APIs nativas de temp del lenguaje. Nunca construyas rutas temporales manualmente con patrones predecibles como /tmp/myapp.pid — son vulnerables a condiciones de carrera y ataques de symlink.
  • Configura trap en Bash o deleteOnExit en Java para garantías de limpieza, pero prefiere limpieza explícita en try-finally o try-with-resources.
  • Usa prefijos y sufijos descriptivos (mktemp prefix.XXXXXX.ext) para identificar el propósito del archivo temp en logs y herramientas del sistema de archivos.
  • Evita escribir secretos en archivos temporales cuando sea posible. Si es inevitable, configura permisos restrictivos (chmod 600) inmediatamente después de la creación.
  • Respeta la variable de entorno $TMPDIR para portabilidad. No hardcodees /tmp — macOS y algunas distros de Linux usan rutas alternativas.

Errores Comunes

  • Hardcodear /tmp con nombres predecibles. Un atacante puede crear un symlink en la ruta esperada para sobrescribir archivos arbitrarios.
  • Depender únicamente de deleteOnExit en procesos de larga duración. Los archivos se acumulan hasta que la JVM o el proceso termina.
  • Olvidar la limpieza en rutas de error. Una excepción antes de la limpieza deja archivos temporales huérfanos que llenan el disco con el tiempo.
  • Usar Date.now() como único aleatorizador en Node.js. Las colisiones de milisegundos son posibles bajo carga — combina con bytes crypto-aleatorios.
  • Crear archivos temporales en el directorio de trabajo. Poluciona el proyecto y puede ser commiteado accidentalmente.

Recursos Relacionados