开发者

nodejs - Temporary file name

In node.js, how do I generate a unique temporary file name, a la mkstemp(3)? I want to ato开发者_JAVA技巧mically write a file using fs.rename.


Another popular package is tmp.


Maybe you already found node-temp in the meantime.


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.


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))


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.


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.


Rather than a temporary file, it may be feasible to create a temporary directory using the built in libraries.

https://nodejs.org/api/fs.html#fspromisesmkdtempprefix-options

import fs from 'node:fs/promises';

let folder = await fs.mkdtemp('foo-');

Knowing that the location you are working in, you can use constant names inside.


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜