Skip to content
SP StackPractices
beginner By StackPractices

Generate Temporary Files

How to create temporary files and directories safely with automatic cleanup across Python, Node.js, Java, and Bash.

Note: This guide follows English-language naming conventions and terminology standards common in international development teams. Examples use English identifiers and comments to maximize compatibility across codebases and tooling.

Overview

Temporary files are essential for caching intermediate data, storing uploads during processing, or holding secrets that should not persist on disk. Creating them incorrectly can lead to security vulnerabilities (predictable filenames), resource leaks (files never deleted), or cross-platform incompatibility.

When to Use

  • Staging uploaded files before validation and permanent storage
  • Holding decrypted data or secrets briefly during processing
  • Caching intermediate computation results within a single process lifetime
  • Running tests that need isolated filesystem state
  • Swapping data that does not fit in memory during batch processing

When NOT to Use

  • Long-term storage of user data — use permanent paths with proper backups
  • Data that must survive process restarts — temp directories may be wiped on reboot
  • Highly sensitive secrets on shared systems — use memory-only approaches or encrypted volumes
  • Files that multiple processes need to discover by name — temp names are randomized

Step-by-Step Implementation

Python

import tempfile
import os

# Temporary file (auto-deleted when closed)
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=True) as f:
    f.write('{"key": "value"}')
    f.flush()
    print(f"Temp file: {f.name}")
    # File is automatically deleted when exiting the context

# Temporary directory (auto-deleted with cleanup=True)
with tempfile.TemporaryDirectory() as tmpdir:
    path = os.path.join(tmpdir, 'report.txt')
    with open(path, 'w') as f:
        f.write('Temporary report data')
    print(f"Temp dir: {tmpdir}")
    # Directory and all contents deleted on context exit

# Manual cleanup (use when passing path to external process)
tmp = tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False)
try:
    tmp.write('id,name\n1,Alice\n')
    tmp.close()
    # Pass tmp.name to external tool...
finally:
    os.unlink(tmp.name)

Node.js

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

// Using built-in fs promises with custom cleanup
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;
    }
}

// Using the tmp package (recommended for production)
import tmp from 'tmp';

// Auto-cleanup on process exit
const tmpObj = tmp.fileSync({ postfix: '.json' });
fs.writeFileSync(tmpObj.name, '{"key": "value"}');
// tmpObj.removeCallback() deletes the file

const tmpDir = tmp.dirSync({ unsafeCleanup: true });
// Recursively removes dir on cleanup

Java

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

// Java 7+ NIO.2 (recommended)
public class TempFileExample {
    public static void main(String[] args) throws IOException {
        // Create temp file in default temp directory
        Path tempFile = Files.createTempFile("prefix-", ".txt");
        System.out.println("Created: " + tempFile);
        Files.writeString(tempFile, "temporary data");

        // Create temp directory
        Path tempDir = Files.createTempDirectory("myapp-");
        Path nested = tempDir.resolve("nested.txt");
        Files.writeString(nested, "nested content");

        // Register for deletion on JVM exit (best effort)
        tempFile.toFile().deleteOnExit();
        tempDir.toFile().deleteOnExit();

        // Explicit cleanup
        Files.deleteIfExists(tempFile);
        Files.walk(tempDir)
            .sorted((a, b) -> -a.compareTo(b))
            .forEach(p -> {
                try { Files.deleteIfExists(p); }
                catch (IOException e) { /* ignore */ }
            });
    }
}

Bash

#!/bin/bash
set -euo pipefail

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

echo '{"status": "ok"}' > "$TMPFILE"
# Process file...
echo "Using: $TMPFILE"

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

# Multiple temp resources — use a cleanup function
cleanup() {
    rm -f "$TMPFILE" 2>/dev/null || true
    rm -rf "$TMPDIR_PATH" 2>/dev/null || true
}
trap cleanup EXIT

# Advanced: generate unique temp path without creating file
UNIQUE_PATH="${TMPDIR:-/tmp}/batch_$(date +%s)_$$_$RANDOM.csv"

Best Practices

  • Always use mktemp or language-native temp APIs. Never build temp paths manually with predictable patterns like /tmp/myapp.pid — they are vulnerable to race conditions and symlink attacks.
  • Set trap in Bash or deleteOnExit in Java for cleanup guarantees, but prefer explicit cleanup in try-finally or try-with-resources.
  • Use descriptive prefixes and suffixes (mktemp prefix.XXXXXX.ext) to identify temp file purpose in logs and filesystem tools.
  • Avoid writing secrets to temp files when possible. If unavoidable, set restrictive permissions (chmod 600) immediately after creation.
  • Respect $TMPDIR environment variable for portability. Do not hardcode /tmp — macOS and some Linux distros use alternate paths.

Common Mistakes

  • Hardcoding /tmp with predictable names. An attacker can create a symlink at the expected path to overwrite arbitrary files.
  • Relying solely on deleteOnExit in long-running processes. Files accumulate until JVM or process exits.
  • Forgetting cleanup in error paths. An exception before cleanup leaves orphaned temp files that fill the disk over time.
  • Using Date.now() as the only randomizer in Node.js. Millisecond collisions are possible under load — combine with crypto-random bytes.
  • Creating temp files in the working directory. Pollutes the project and may be committed accidentally.