【问题标题】:How to create a tmp dir in node without collisions如何在没有冲突的节点中创建 tmp 目录
【发布时间】:2016-06-14 12:09:56
【问题描述】:

我需要在 node.js 中按需创建一个临时的“scratch”目录。要求是:

  • 目录名应该是随机的(即/tmp/aDIge4G/
  • 该目录将在/tmp 中创建,其中可能已经有其他随机命名的目录。
  • 如果目录已经存在,我应该扔掉而不是使用它并覆盖别人的工作
  • 这需要在并发环境中是安全的。我不能只检查目录是否存在,如果不存在则创建它,因为其他人可能在我检查之后 创建了同名目录。

换句话说,我需要this 问题的答案,但需要的是目录,而不是文件。

This 回答说我想做的事情可以通过mkdir -p 完成,但是Node 没有fs.mkdir-p 标志

【问题讨论】:

    标签: javascript node.js file concurrency directory


    【解决方案1】:

    您可以使用fs-jetpack 库的tmpDir 方法。它仅在下面使用crypto.randomBytes 并生成 128 位熵随机字符串作为目录名称。如果您创建 2^32(40 亿)个临时目录,统计名称碰撞机会仍然是 1 到 2^96,这与我这一秒被陨石击中的可能性相同(不知何故我忍受了这个)恐惧;)。

    依靠大数字的概率(顺便说一句,这就是 git-hashes 所做的)比试图找出一些在并发环境中省略名称冲突的巧妙方法要好得多,也更简单。

    示例代码:

    const jetpack = require("fs-jetpack");
    
    const tmp = jetpack.tmpDir();
    
    // Do some stuff in the directory...
    tmp.write("some_stuff.txt", "Hi!");
    
    // After you're done with your directory easily remove it.
    tmp.remove();
    

    【讨论】:

      【解决方案2】:

      当前节点api建议创建一个临时文件夹:https://nodejs.org/api/fs.html#fs_fs_mkdtemp_prefix_options_callback

      给出:

      fs.mkdtemp(path.join(os.tmpdir(), 'foo-'), (err, folder) => {
        if (err) throw err;
        console.log(folder);
        // Prints: /tmp/foo-itXde2
      });
      // folder /tmp/foo-itXde2 has been created on the file system
      

      【讨论】:

        【解决方案3】:

        创建唯一目录的一种简单方法是在路径名中使用universally unique identifiers (UUID)。

        这里是一个使用pure-uuid的例子:

        const fs = require('fs-extra');
        const path = require('path');
        const UUID = require('pure-uuid');
        
        const id = new UUID(4).format();
        const directory = path.join('.', 'temp', id);
        
        fs.mkdirs(directory).then(() => {
          console.log(`Created directory: ${directory}`);
        });
        

        你会得到这样的输出:

        创建的目录:temp\165df8b8-18cd-4151-84ca-d763e2301e14

        注意:在上面的代码中,我使用fs-extra 作为fs 的替代品,所以你不必关心mkdir -p,因为fs-extra 会创建目录和任何必要的子目录。

        提示:如果要将目录保存在操作系统的默认临时目录中,则可以使用os.tmpdir()。以下是其工作原理的示例:

        const fs = require('fs-extra');
        const os = require('os');
        const path = require('path');
        const UUID = require('pure-uuid');
        
        const id = new UUID(4).format();
        const directory = path.join(os.tmpdir(), id);
        
        fs.mkdirs(directory).then(() => {
          console.log(`Created directory: ${directory}`);
        });
        

        创建的目录:C:\Users\bennyn\AppData\Local\Temp\057a9978-4fd7-43d9-b5ea-db169f222dba

        【讨论】:

          【解决方案4】:

          你可以试试package "tmp"。它有一个配置参数“模板”,它反过来使用 Linux 的 mkstemp 函数,这可能会解决您的所有要求。

          【讨论】:

          • 我应该在我的存储库中安装另一个已经有 16657 个依赖项的包吗?...它要去哪里?
          【解决方案5】:

          使用fs.Stats检查是否存在?

          这样的?

          fs.stat(path, function(err, stats) {
          
              if (!stats.isDirectory()) {
                  // create directory here
              }
          }
          

          【讨论】:

          • 如果别人在我做的时候创建了一个目录怎么办if (!stats.isDirectory())
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-14
          • 1970-01-01
          • 2016-12-29
          • 2016-04-15
          • 2015-03-08
          • 1970-01-01
          相关资源
          最近更新 更多