Temporary files and directories are useful for storing data that isn’t needed after a program exits. They help keep the file system clean and avoid polluting it with leftover files.
Why Use Temporary Files?
Temporary files and directories are automatically created in system-appropriate locations (like /tmp on Unix) and can be automatically cleaned up by the operating system.
Use Cases
Intermediate processing data
Cache storage
Testing and development
Build artifacts
Downloaded files before validation
Creating Temporary Files
Use os.CreateTemp to create a temporary file:
package main
import (
" fmt "
" os "
)
func check ( e error ) {
if e != nil {
panic ( e )
}
}
func main () {
// Create temporary file
f , err := os . CreateTemp ( "" , "sample" )
check ( err )
fmt . Println ( "Temp file name:" , f . Name ())
// Output (Unix): Temp file name: /tmp/sample123456789
}
os.CreateTemp creates the file AND opens it for reading and writing. The file is ready to use immediately.
Understanding CreateTemp Parameters
f , err := os . CreateTemp ( dir , pattern )
First Parameter: Directory
Empty string "": Use default temp directory (recommended)
Specific path: Create temp file in that directory
Second Parameter: Pattern
Prefix for the filename
Random string is appended automatically
Ensures concurrent calls create different filenames
Passing an empty string "" as the first argument uses the system’s default temporary directory, which is /tmp on Unix-based systems and the TEMP directory on Windows.
Cleaning Up Temporary Files
Always remove temporary files when done:
f , err := os . CreateTemp ( "" , "sample" )
check ( err )
// Clean up when done
defer os . Remove ( f . Name ())
// Use the file
_ , err = f . Write ([] byte { 1 , 2 , 3 , 4 })
check ( err )
While the OS may clean up temporary files eventually, it’s good practice to explicitly remove them when your program finishes using them.
Writing to Temporary Files
f , err := os . CreateTemp ( "" , "sample" )
check ( err )
defer os . Remove ( f . Name ())
// File is already open for reading and writing
_ , err = f . Write ([] byte { 1 , 2 , 3 , 4 })
check ( err )
// Close when done writing
f . Close ()
Creating Temporary Directories
Use os.MkdirTemp to create a temporary directory:
import " path/filepath "
// Create temporary directory
dname , err := os . MkdirTemp ( "" , "sampledir" )
check ( err )
fmt . Println ( "Temp dir name:" , dname )
// Output (Unix): Temp dir name: /tmp/sampledir123456789
// Clean up directory and all contents
defer os . RemoveAll ( dname )
os.MkdirTemp returns the directory name (not an open file). You can then create files inside it.
Creating Files in Temporary Directory
// Create temp directory
dname , err := os . MkdirTemp ( "" , "sampledir" )
check ( err )
defer os . RemoveAll ( dname )
// Create file inside temp directory
fname := filepath . Join ( dname , "file1" )
err = os . WriteFile ( fname , [] byte { 1 , 2 }, 0666 )
check ( err )
Use filepath.Join to construct paths inside the temporary directory to ensure cross-platform compatibility.
Complete Example
package main
import (
" fmt "
" os "
" path/filepath "
)
func check ( e error ) {
if e != nil {
panic ( e )
}
}
func main () {
// Create temporary file
f , err := os . CreateTemp ( "" , "sample" )
check ( err )
fmt . Println ( "Temp file name:" , f . Name ())
// Clean up file
defer os . Remove ( f . Name ())
// Write to file
_ , err = f . Write ([] byte { 1 , 2 , 3 , 4 })
check ( err )
// Create temporary directory
dname , err := os . MkdirTemp ( "" , "sampledir" )
check ( err )
fmt . Println ( "Temp dir name:" , dname )
// Clean up directory
defer os . RemoveAll ( dname )
// Create file in temp directory
fname := filepath . Join ( dname , "file1" )
err = os . WriteFile ( fname , [] byte { 1 , 2 }, 0666 )
check ( err )
}
Common Patterns
Single Temp File
Temp Directory
Multiple Temp Files
Test Fixture
f , err := os . CreateTemp ( "" , "prefix-" )
if err != nil {
log . Fatal ( err )
}
defer os . Remove ( f . Name ())
defer f . Close ()
// Use file...
dir , err := os . MkdirTemp ( "" , "prefix-" )
if err != nil {
log . Fatal ( err )
}
defer os . RemoveAll ( dir )
// Create files in directory...
dir , err := os . MkdirTemp ( "" , "workdir-" )
if err != nil {
log . Fatal ( err )
}
defer os . RemoveAll ( dir )
// Create multiple files
for i := 0 ; i < 10 ; i ++ {
fname := filepath . Join ( dir , fmt . Sprintf ( "file %d " , i ))
os . WriteFile ( fname , data , 0644 )
}
func TestSomething ( t * testing . T ) {
dir , err := os . MkdirTemp ( "" , "test-" )
if err != nil {
t . Fatal ( err )
}
defer os . RemoveAll ( dir )
// Test code using temp directory...
}
File Permissions
Temporary Files
f , err := os . CreateTemp ( "" , "prefix-" )
// File is created with permissions 0600 (read/write for owner only)
Temporary Directories
dir , err := os . MkdirTemp ( "" , "prefix-" )
// Directory is created with permissions 0700 (rwx for owner only)
Temporary files and directories are created with restrictive permissions by default for security. Only the owner can access them.
Advanced Usage
Custom Temp Location
// Create temp file in specific directory
customDir := "/var/app/temp"
f , err := os . CreateTemp ( customDir , "prefix-" )
check ( err )
defer os . Remove ( f . Name ())
Getting System Temp Directory
tempDir := os . TempDir ()
fmt . Println ( "System temp directory:" , tempDir )
// Unix: /tmp
// Windows: C:\Users\username\AppData\Local\Temp
Structured Temp Directories
// Create structured temp workspace
workDir , err := os . MkdirTemp ( "" , "build-" )
check ( err )
defer os . RemoveAll ( workDir )
// Create subdirectories
os . MkdirAll ( filepath . Join ( workDir , "src" ), 0755 )
os . MkdirAll ( filepath . Join ( workDir , "bin" ), 0755 )
os . MkdirAll ( filepath . Join ( workDir , "tmp" ), 0755 )
Best Practices
Use defer to ensure temporary files and directories are removed, even if errors occur: f , err := os . CreateTemp ( "" , "prefix-" )
check ( err )
defer os . Remove ( f . Name ())
Use descriptive prefixes to make temp files identifiable: f , err := os . CreateTemp ( "" , "image-processing-" )
f , err := os . CreateTemp ( "" , "test-data-" )
Prefer directories for multiple files
If you need multiple temporary files, create a temp directory and put files inside it. This makes cleanup easier.
Close files before removing
On Windows, you must close a file before removing it: f , _ := os . CreateTemp ( "" , "prefix-" )
f . Close () // Close before removing
os . Remove ( f . Name ())
Use os.RemoveAll for directories
Always use os.RemoveAll for temporary directories to remove all contents: dir , _ := os . MkdirTemp ( "" , "prefix-" )
defer os . RemoveAll ( dir ) // Not os.Remove
Handle cleanup errors in production
In production code, log cleanup errors instead of panicking: defer func () {
if err := os . RemoveAll ( dir ); err != nil {
log . Printf ( "Failed to remove temp dir: %v " , err )
}
}()
Testing with Temporary Files
func TestFileProcessing ( t * testing . T ) {
// Create temp directory for test
testDir , err := os . MkdirTemp ( "" , "test-" )
if err != nil {
t . Fatal ( err )
}
defer os . RemoveAll ( testDir )
// Create test file
testFile := filepath . Join ( testDir , "input.txt" )
err = os . WriteFile ( testFile , [] byte ( "test data" ), 0644 )
if err != nil {
t . Fatal ( err )
}
// Run test with temp file
result , err := ProcessFile ( testFile )
if err != nil {
t . Errorf ( "ProcessFile failed: %v " , err )
}
// Verify result...
}
Comparison Table
Function Returns Use For os.CreateTemp*os.File (open file)Single temporary file os.MkdirTempstring (directory path)Temporary directory os.RemoveRemoves file or empty dir Cleanup single file os.RemoveAllRemoves dir and contents Cleanup directory tree
Writing Files Learn how to write data to files
Directories Working with directories in Go
File Paths Portable file path operations