使用 FileReader() 读取文件以从图像文件生成 md5 哈希字符串的正确方法?
Proper way to read a file using FileReader() to generate an md5 hash string from image files?
我目前正在执行此操作(请参阅下面的代码片段)以获取我正在上传的图像文件的 md5
哈希字符串(我将哈希用作 fileNames
):
注意: 我正在使用 md5
包生成哈希(它已加载到代码段中)。
FileReader()
上有 4 种可用的方法来读取文件。他们似乎都产生了不错的结果。
- readAsText(文件)
- readAsBinaryString(文件);
- readAsArrayBuffer(文件);
- readAsDataURL(文件);
在这种情况下我应该使用哪个?为什么?能不能也解释一下它们的区别?
function onFileSelect(e) {
const file = e.target.files[0];
const reader1 = new FileReader();
const reader2 = new FileReader();
const reader3 = new FileReader();
const reader4 = new FileReader();
reader1.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsText()": ');
console.log(md5(fileContent));
}
reader2.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsBinaryString()": ');
console.log(md5(fileContent));
}
reader3.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsArrayBuffer()": ');
console.log(md5(fileContent));
}
reader4.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsDataURL()": ');
console.log(md5(fileContent));
}
reader1.readAsText(file);
reader2.readAsBinaryString(file);
reader3.readAsArrayBuffer(file);
reader4.readAsDataURL(file);
}
.myDiv {
margin-bottom: 10px;
}
<script src="https://cdn.jsdelivr.net/npm/js-md5@0.7.3/src/md5.min.js"></script>
<div class="myDiv">Pick an image file to see the 4 hash results on console.log()</div>
<input type='file' onChange="onFileSelect(event)" accept='.jpg,.jpeg,.png,.gif' />
使用readAsArrayBuffer
.
readAsBinaryString()
和 readAsDataURL()
将使您的计算机完成比需要完成的工作更多的工作:
- 将 blob 读取为二进制流
- 转换为 UTF-16 / base64 字符串(记住字符串在 js 中是不可变的,你对它做的任何操作实际上都会在内存中创建一个副本)
- [传递给你的库]
- 转换为二进制字符串
- 处理数据
此外,您的库似乎不处理数据 URL,并且在 UTF-16 字符串上失败。
readAsText()
默认情况下会尝试将您的二进制数据解释为 UTF-8 文本序列,这对于像光栅图像这样的二进制数据来说非常糟糕:
// generate some binary data
document.createElement('canvas').toBlob(blob => {
const utf8_reader = new FileReader();
const bin_reader = new FileReader();
let done = 0;
utf8_reader.onload = bin_reader.onload = e => {
if(++done===2) {
console.log('same results: ', bin_reader.result === utf8_reader.result);
console.log("utf8\n", utf8_reader.result);
console.log("utf16\n", bin_reader.result);
}
}
utf8_reader.readAsText(blob);
bin_reader.readAsBinaryString(blob);
});
另一方面,readAsArrayBuffer
只会按内存中的原样分配二进制数据。简单I/O,没有处理。
要操作这些数据,我们可以对这个二进制数据使用 TypedArrays 视图,它只是视图,不会产生任何开销。
如果您查看 the library you are using,他们无论如何都会将您的输入传递给这样的 Uint8Array 以进一步处理它。但是请注意,他们显然需要您传递此 ArrayBuffer 的 Uint8Array 视图,而不是直接传递裸 ArrayBuffer。
我目前正在执行此操作(请参阅下面的代码片段)以获取我正在上传的图像文件的 md5
哈希字符串(我将哈希用作 fileNames
):
注意: 我正在使用 md5
包生成哈希(它已加载到代码段中)。
FileReader()
上有 4 种可用的方法来读取文件。他们似乎都产生了不错的结果。
- readAsText(文件)
- readAsBinaryString(文件);
- readAsArrayBuffer(文件);
- readAsDataURL(文件);
在这种情况下我应该使用哪个?为什么?能不能也解释一下它们的区别?
function onFileSelect(e) {
const file = e.target.files[0];
const reader1 = new FileReader();
const reader2 = new FileReader();
const reader3 = new FileReader();
const reader4 = new FileReader();
reader1.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsText()": ');
console.log(md5(fileContent));
}
reader2.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsBinaryString()": ');
console.log(md5(fileContent));
}
reader3.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsArrayBuffer()": ');
console.log(md5(fileContent));
}
reader4.onload = (event) => {
const fileContent = event.target.result;
console.log('Hash from "readAsDataURL()": ');
console.log(md5(fileContent));
}
reader1.readAsText(file);
reader2.readAsBinaryString(file);
reader3.readAsArrayBuffer(file);
reader4.readAsDataURL(file);
}
.myDiv {
margin-bottom: 10px;
}
<script src="https://cdn.jsdelivr.net/npm/js-md5@0.7.3/src/md5.min.js"></script>
<div class="myDiv">Pick an image file to see the 4 hash results on console.log()</div>
<input type='file' onChange="onFileSelect(event)" accept='.jpg,.jpeg,.png,.gif' />
使用readAsArrayBuffer
.
readAsBinaryString()
和 readAsDataURL()
将使您的计算机完成比需要完成的工作更多的工作:
- 将 blob 读取为二进制流
- 转换为 UTF-16 / base64 字符串(记住字符串在 js 中是不可变的,你对它做的任何操作实际上都会在内存中创建一个副本)
- [传递给你的库]
- 转换为二进制字符串
- 处理数据
此外,您的库似乎不处理数据 URL,并且在 UTF-16 字符串上失败。
readAsText()
默认情况下会尝试将您的二进制数据解释为 UTF-8 文本序列,这对于像光栅图像这样的二进制数据来说非常糟糕:
// generate some binary data
document.createElement('canvas').toBlob(blob => {
const utf8_reader = new FileReader();
const bin_reader = new FileReader();
let done = 0;
utf8_reader.onload = bin_reader.onload = e => {
if(++done===2) {
console.log('same results: ', bin_reader.result === utf8_reader.result);
console.log("utf8\n", utf8_reader.result);
console.log("utf16\n", bin_reader.result);
}
}
utf8_reader.readAsText(blob);
bin_reader.readAsBinaryString(blob);
});
readAsArrayBuffer
只会按内存中的原样分配二进制数据。简单I/O,没有处理。
要操作这些数据,我们可以对这个二进制数据使用 TypedArrays 视图,它只是视图,不会产生任何开销。
如果您查看 the library you are using,他们无论如何都会将您的输入传递给这样的 Uint8Array 以进一步处理它。但是请注意,他们显然需要您传递此 ArrayBuffer 的 Uint8Array 视图,而不是直接传递裸 ArrayBuffer。