javascript - NodeJS - 从流与本地文件生成哈希时的不同结果
问题描述
似乎如果我散列一个文件流,我得到的散列与我将流写入磁盘、读回然后散列它不同。可能是编码问题,或者我错了哈希应该相同?
这是我的测试用例
const fs = require("fs");
const crypto = require("crypto");
const https = require("https");
(async ()=>{
const testUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/SIPI_Jelly_Beans_4.1.07.tiff/lossy-page1-256px-SIPI_Jelly_Beans_4.1.07.tiff.jpg"
const filePath = "./testFile.jpg";
https.get(testUrl, async function(response) {
await writeFile(filePath, response);
const streamHash = await hashFileStream(response)
const fileHash = await hashLocalFile(filePath)
console.log("Stream Hash", streamHash);
console.log("File hash", fileHash);
});
})()
async function writeFile(filePath, stream) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(filePath);
stream.pipe(file)
.on('finish', () => {
resolve(filePath);
})
.on('error', (error)=>{
console.error(error);
reject(error);
})
})
}
async function hashFileStream(stream){
return new Promise((resolve, reject)=>{
const hash = crypto.createHash('md5').setEncoding('hex');
stream.pipe(hash)
.on('finish', ()=>{
resolve(hash.read())
})
.on('error', (error)=>{
reject(error)
})
})
}
async function hashLocalFile(filepath){
const readStream = fs.createReadStream(filepath);
return hashFileStream(readStream);
}
解决方案
那是你的错误。根据节点 js 文件:
调用 stream.end() 方法后会发出“完成”事件,并且所有数据都已刷新到底层系统。
当函数中发出完成事件时,writeFile
流完成写入数据,hashFileStream
函数没有任何剩余。
如果您只想检查哈希字符串,最简单的方法是分离代码并看到它们是相同的:
const fs = require("fs");
const crypto = require("crypto");
const https = require("https");
(async ()=>{
const filePath = "./testFile.jpg";
const testUrl = "https://static2.farakav.com/files/pictures/watermark/01661368.jpg"
https.get(testUrl, async function(response) {
await writeFile(filePath, response);
const fileHash = await hashLocalFile(filePath)
console.log("File hash", fileHash);
});
https.get(testUrl, async function(response) {
const streamHash = await hashFileStream(response)
console.log("Stream Hash", streamHash);
});
})()
async function writeFile(filePath, stream) {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(filePath);
stream.pipe(file)
.on('finish', () => {
resolve(filePath);
})
.on('error', (error)=>{
console.error(error);
reject(error);
})
})
}
async function hashFileStream(stream){
return new Promise((resolve, reject)=>{
const hash = crypto.createHash('md5').setEncoding('hex');
stream.pipe(hash)
.on('finish', ()=>{
hash.end();
resolve(hash.read())
})
.on('error', (error)=>{
reject(error)
})
})
}
async function hashLocalFile(filepath){
const readStream = fs.createReadStream(filepath);
return hashFileStream(readStream);
}
推荐阅读
- c# - C# VSTO SaveCopyAs 签入的演示文稿/文档
- python - 组内组的长度(在 groupby 之后应用 groupby)
- javascript - 如何使自动建议的建议溢出对话框容器?
- php - PHP、Ajax 和 MySQL 中的文本框中的自动完成
- python-3.x - 为什么我在 100 行数据帧上执行 pyspark 命令需要 30 多分钟才能执行?
- python-3.x - 在 python 中使用灵活的文本匹配执行重复数据删除
- wpf - 如何从 WPF 中的 CS 文件中调用 Grid
- android - 进度条不显示,UI 线程似乎挂起
- asp.net-mvc - 即使将默认设置为空字符串,也获取属性的空值
- apache-flink - 使用 timeWindow 和 processingTime 但数据摄取被阻止