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
How to check if two files have the same content?
提问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.js
that 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.js
you can use .eql
to 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-compare
and 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.eql
takes 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 Sync
calls with something like the following code. Also, I would use the method equals
that Max
suggest to compare both files:
所以,我会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')
}
});
});
Though for a small and a single script the result would be almost the same
虽然对于一个小脚本和单个脚本,结果几乎相同