簡體   English   中英

如何檢查兩個文件是否具有相同的內容?

[英]How to check if two files have the same content?

我正在使用 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();
    });
});

令人驚訝的是,沒有人建議使用Buffer.equals 這似乎是最快和最簡單的方法,並且自 v0.11 以來一直存在。

所以你的代碼會變成tmpBuf.equals(testBuf)

您有 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) 方法。

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

使用file-comparenode-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);
});

為了在斷言文件上傳時比較大文件(例如圖像),緩沖區或字符串與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)

而不是使用shouldjs作為斷言模塊,你肯定可以使用不同的工具

我認為你應該在 JavaScript 中使用非阻塞調用來獲得更好的性能,至少可以防止阻塞其他操作:

阻塞是指 Node.js 進程中額外 JavaScript 的執行必須等到非 JavaScript 操作完成。 發生這種情況是因為在發生阻塞操作時,事件循環無法繼續運行 JavaScript。

在 Node.js 中,由於 CPU 密集型而不是等待非 JavaScript 操作(例如 I/O)而表現出較差性能的 JavaScript 通常不稱為阻塞。 Node.js 標准庫中使用 libuv 的同步方法是最常用的阻塞操作。 本機模塊也可能有阻塞方法。

因此,我將使用類似以下代碼的內容更改Sync調用。 另外,我會使用Max建議的方法equals來比較兩個文件:

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

    });
});

雖然對於一個小腳本和單個腳本,結果幾乎相同

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM