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
mktempor 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
trapin Bash ordeleteOnExitin 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
$TMPDIRenvironment variable for portability. Do not hardcode/tmp— macOS and some Linux distros use alternate paths.
Common Mistakes
- Hardcoding
/tmpwith predictable names. An attacker can create a symlink at the expected path to overwrite arbitrary files. - Relying solely on
deleteOnExitin 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.