代码之家  ›  专栏  ›  技术社区  ›  hellboy Justin Pihony

如何检查两个文件是否具有相同的内容?

  •  34
  • hellboy Justin Pihony  · 技术社区  · 10 年前

    我正在使用 mocha/supertest/should.js 测试REST服务

    GET /files/<hash> 将文件作为流返回。

    我如何在 should.js 文件内容是否相同?

    it('should return file as stream', function (done) {
        var writeStream = fs.createWriteStream('test/fixtures/tmp.json');
        
        var req = api.get('/files/676dfg1430af3595');
        req.on('end', function(){
           var tmpBuf = fs.readFileSync('test/fixtures/tmp.json');
           var testBuf = fs.readFileSync('test/fixtures/test.json');
        
           // How to assert with should.js file contents are the same (tmpBuf == testBuf )
           // ...
        
           done();
        });
    });
    
    6 回复  |  直到 3 年前
        1
  •  49
  •   Max    7 年前

    令人惊讶的是,没有人提出 Buffer.equals 。这似乎是最快和最简单的方法,从v0.11开始就有了。

    所以你的代码会变成 tmpBuf.equals(testBuf)

        2
  •  4
  •   micnic    10 年前

    您有3种解决方案:

    第一 :

    比较结果字符串

    tmpBuf.toString() === testBuf.toString();
    

    第二 :

    使用循环逐字节读取缓冲区

    var index = 0,
        length = tmpBuf.length,
        match = true;
    
    while (index < length) {
        if (tmpBuf[index] === testBuf[index]) {
            index++;
        } else {
            match = false;
            break;
        }
    }
    
    match; // true -> contents are the same, false -> otherwise
    

    第三 :

    使用第三方模块,如 buffertools 和buffertools.compare(buffer,buffer|string)方法。

        3
  •  4
  •   den bardadym hakatashi    10 年前

    在里面 should.js 你可以使用 .eql 要比较Buffer的实例:

    > var buf1 = new Buffer('abc');
    undefined
    > var buf2 = new Buffer('abc');
    undefined
    > var buf3 = new Buffer('dsfg');
    undefined
    > buf1.should.be.eql(buf1)
    ...
    > buf1.should.be.eql(buf2)
    ...
    > buf1.should.be.eql(buf3)
    AssertionError: expected <Buffer 61 62 63> to equal <Buffer 64 73 66 67>
        ...
    > 
    
        4
  •  4
  •   smoebody    8 年前

    用于在断言文件上载时比较大文件(例如图像),将缓冲区或字符串与 should.eql 需要很长时间。我建议使用 密码 模块:

    const buf1Hash = crypto.createHash('sha256').update(buf1).digest();
    const buf2Hash = crypto.createHash('sha256').update(buf2).digest();
    buf1Hash.should.eql(buf2Hash);
    

    一种更简单的方法是这样断言缓冲区长度:

    buf1.length.should.eql(buf2.length)
    

    而不是使用 应该 作为断言模块,您肯定可以使用不同的工具

        5
  •  3
  •   hellboy Justin Pihony    10 年前

    解决方案使用 file-compare node-temp :

    it('should return test2.json as a stream', function (done) {
        var writeStream = temp.createWriteStream();
        temp.track();
    
        var req = api.get('/files/7386afde8992');
    
        req.on('end', function() {
            comparator.compare(writeStream.path, TEST2_JSON_FILE, function(result, err) {
                if (err) {
                    return done(err);
                }
    
                result.should.true;
                done();
            });
        });
    
        req.pipe(writeStream);
    });
    
        6
  •  1
  •   Community Mofi    4 年前

    我认为你应该使用 non-blocking calls 在JavaScript中获得更好的性能,至少防止阻止其他操作:

    阻塞是指Node.js进程中附加JavaScript的执行必须等待非JavaScript操作完成。发生这种情况是因为在发生阻塞操作时,事件循环无法继续运行JavaScript。

    在Node.js中,由于CPU密集而不是等待非JavaScript操作(如I/O)而表现出较差性能的JavaScript通常不被称为阻塞。Node.js标准库中使用libuv的同步方法是最常用的阻塞操作。本机模块也可能具有阻塞方法。

    所以,我会改变 Sync 调用,类似以下代码。此外,我会使用该方法 equals 那个 Max 建议比较两个文件:

    const fs = require('fs')
    
    fs.readFile('file1', (err, data1) => {
        if (err) throw err;
        fs.readFile('file2', (err, data2) => {
            if (err) throw err;
            if (data1.equals(data2)) {
                console.log('EQUAL')
            } else {
                console.log('NON EQUAL')
            }
    
        });
    });
    

    尽管对于一个小而单一的脚本,结果几乎相同