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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25783161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 05:00:36  来源:igfitidea点击:

How to check if two files have the same content?

javascriptnode.jscomparemochashould.js

提问by hellboy

I am using mocha/supertest/should.js to test my Rest Service

我正在使用 mocha/supertest/should.js 来测试我的 Rest 服务

GET /files/<hash>returns file as stream.

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

How can I assert in should.jsthat file contents are the same?

我如何断言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();
    });
});

回答by Max

Surprisingly, no one has suggested Buffer.equals. That seems to be the fastest and simplest approach and has been around since v0.11.

令人惊讶的是,没有人建议使用Buffer.equals。这似乎是最快和最简单的方法,并且自 v0.11 以来一直存在。

So your code would become tmpBuf.equals(testBuf)

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

回答by micnic

You have 3 solutions:

您有 3 个解决方案:

First:

第一

Compare the result strings

比较结果字符串

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

Second:

第二

Using a loop to read the buffers byte by byte

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

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

Third:

第三

Using a third-party module like buffertoolsand buffertools.compare(buffer, buffer|string) method.

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

回答by den bardadym

In should.jsyou can use .eqlto compare Buffer's instances:

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

回答by hellboy

Solution using file-compareand node-temp:

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

回答by smoebody

for comparing large files e.g. images when asserting file uploads a comparison of buffers or strings with should.eqltakes ages. i recommend asserting the buffer hash with the cryptomodule:

为了在断言文件上传时比较大文件(例如图像),should.eql需要对缓冲区或字符串进行比较。我建议使用加密模块断言缓冲区哈希:

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

an easier approach is asserting the buffer length like so:

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

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

instead of using shouldjsas assertion module you can surely use a different tool

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

回答by ChesuCR

I think that you should use non-blocking callsin JavaScript to get a better performance, at least to prevent from blocking other operations:

我认为你应该在 JavaScript 中使用非阻塞调用来获得更好的性能,至少可以防止阻塞其他操作:

Blocking is when the execution of additional JavaScript in the Node.js process must wait until a non-JavaScript operation completes. This happens because the event loop is unable to continue running JavaScript while a blocking operation is occurring.

In Node.js, JavaScript that exhibits poor performance due to being CPU intensive rather than waiting on a non-JavaScript operation, such as I/O, isn't typically referred to as blocking. Synchronous methods in the Node.js standard library that use libuv are the most commonly used blocking operations. Native modules may also have blocking methods.

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

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

So, I would change the Synccalls with something like the following code. Also, I would use the method equalsthat Maxsuggest to compare both files:

所以,我会Sync用类似下面的代码来改变调用。另外,我想使用的方法equalsMax建议来比较两个文件:

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

    });
});

Though for a small and a single script the result would be almost the same

虽然对于一个小脚本和单个脚本,结果几乎相同