nodejs - Temporary file name

node.js

node.js Problem Overview


In node.js, how do I generate a unique temporary file name, a la mkstemp(3)? I want to atomically write a file using fs.rename.

node.js Solutions


Solution 1 - node.js

Another popular package is tmp.

Solution 2 - node.js

Maybe you already found node-temp in the meantime.

Solution 3 - node.js

Without using any additional plugins:

var crypto = require('crypto');
var fs = require('fs'); 

var filename = 'foo'+crypto.randomBytes(4).readUInt32LE(0)+'bar';
fs.writeFileSync(filename, 'baz');

EDIT: read comments.

Solution 4 - node.js

Try this function, secure and without vulnerabilities. NODE 8.x LTS

function tempFile (name = 'temp_file', data = '', encoding = 'utf8') {
    const fs = require('fs');
    const os = require('os');
    const path = require('path');

    return new Promise((resolve, reject) => {
        const tempPath = path.join(os.tmpdir(), 'foobar-');
        fs.mkdtemp(tempPath, (err, folder) => {
            if (err) 
                return reject(err)
        
            const file_name = path.join(folder, name);
        
            fs.writeFile(file_name, data, encoding, error_file => {
                if (error_file) 
                    return reject(error_file);

                resolve(file_name)
            })
        })
    })
}

It resolves the PATH of the temp file, rejects mkdtemp or writeFile errors

// C:\Users\MYPC\AppData\Local\Temp\foobar-3HmKod\temp_file
// /temp/Temp/foobar-3HmKod/temp_file
tempFile().then(path => console.log(path)).catch(e => console.log("error", e)) //or

// C:\Users\MYPC\AppData\Local\Temp\foobar-9KHuxg\hola.txt
// /temp/Temp/foobar-9KHuxg/hola.txt
tempFile('hola.txt', 'hello there').then(path => console.log(path)).catch(e => console.log("e", e))

Solution 5 - node.js

Temp file creation in node and python suffer from race conditions involving permission changes, and cross-platform issues, especially on Windows where it's challenging to test ACL's.

The result is that it can literally hang your machine asking for a temp file in many modern languages. (If node doesn't have access to the temp dir, depending on the ACLs, it can get EEXIST, even when the file doesn't exist - the result of which can be an infinite loop.).

The simplest solution is to use enough entropy that the likelihood of a collision is negligible (in the cryptographic sense).

This also has the side effect of making temp file creation secure across all platforms, without needing to heavily vet the source code. As long as your random numbers are secure, there is no way to predict the file that will be used to usurp permissions or access.

And it helps with programs that need to pass file names around, not file handles.

const crypto = require('crypto');
const os = require('os'); 
const path = require('path'); 

function tmpFile(prefix, suffix, tmpdir) {
    prefix = (typeof prefix !== 'undefined') ? prefix : 'tmp.';
    suffix = (typeof suffix !== 'undefined') ? suffix : '';
    tmpdir = tmpdir ? tmpdir : os.tmpdir();
    return path.join(tmpdir, prefix + crypto.randomBytes(16).toString('hex') + suffix);
}

The only disadvantage is that this will not work on FAT formatted partitions, which can still be common on USB sticks.

Solution 6 - node.js

Similar to kinematic's answer, but with 2 bytes extra entropy and letters instead of numbers:

import Crypto from 'crypto';
import {tmpdir} from 'os';
import Path from 'path';

function tmpFile(ext) {
    return Path.join(tmpdir(),`archive.${Crypto.randomBytes(6).readUIntLE(0,6).toString(36)}.${ext}`);
}

Usage:

const file = tmpFile('tar.gz'); // "/tmp/archive.1scpz5ew5d.tar.gz"

I'm creating archives, so I chose "archive" as the basename, but you can change it as you see fit.

Solution 7 - node.js

use npm package tempfile

import tempfile from 'tempfile';

Or

let tempfile = "";
import('tempfile').then(a => {
    tempfile = a.default;
});

and then:

let filename = tempfile() //e,g: /tmp/5fc8a50f-e9cd-4420-b62a-e365b3ef2c2a
let imagefilename = tempfile(".jpeg") // e,g: /tmp/5a6dea08-a704-4fa8-9d0a-8ffa5e134543.jpeg

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnornagonView Question on Stackoverflow
Solution 1 - node.jsSteve JansenView Answer on Stackoverflow
Solution 2 - node.jsMarcView Answer on Stackoverflow
Solution 3 - node.jskinematicView Answer on Stackoverflow
Solution 4 - node.jsFernando CarvajalView Answer on Stackoverflow
Solution 5 - node.jsErik AronestyView Answer on Stackoverflow
Solution 6 - node.jsmpenView Answer on Stackoverflow
Solution 7 - node.jsOhad CohenView Answer on Stackoverflow