Javascript FileReader().readAsArrayBuffer(文件)结果在第一次加载文件后被卡住

Javascript FileReader().readAsArrayBuffer(文件)结果在第一次加载文件后被卡住,javascript,reactjs,browser,filereader,arraybuffer,Javascript,Reactjs,Browser,Filereader,Arraybuffer,我正在使用此代码生成一个md5哈希字符串,用作存储中的文件名。我读取文件(图像)内容并使用md5库计算哈希值 不知怎的,FileReader()API的readAsArrayBuffer(file)方法的结果在我读取第一个文件后被卡住了 代码沙盒: 如果我将读取方法更改为readAsText(file),则结果似乎正常,并且对于不同的文件,我会得到不同的哈希值。但是有人告诉我,readAsArrayBuffer()对图像文件更有意义。这就是我使用它的原因 会发生什么?我需要清除一些缓冲区吗 奇怪

我正在使用此代码生成一个
md5
哈希字符串,用作存储中的文件名。我读取文件(图像)内容并使用
md5
库计算哈希值

不知怎的,
FileReader()
API的
readAsArrayBuffer(file)
方法的结果在我读取第一个文件后被卡住了

代码沙盒:

如果我将读取方法更改为
readAsText(file)
,则结果似乎正常,并且对于不同的文件,我会得到不同的哈希值。但是有人告诉我,
readAsArrayBuffer()
对图像文件更有意义。这就是我使用它的原因

会发生什么?我需要清除一些缓冲区吗

奇怪行为的GIF:

EDIT:事实证明,您需要从
ArrayBuffer
创建一个类型化数组,以处理
readAsArrayBuffer()的结果

发件人:

ArrayBuffer对象用于表示通用的固定长度原始二进制数据缓冲区

它是一个字节数组,在其他语言中通常称为“字节数组”

不能直接操作ArrayBuffer的内容;相反,您可以创建一个类型化数组对象或一个以特定格式表示缓冲区的DataView对象,并使用该对象读取和写入缓冲区的内容

import React,{useState}来自“React”;
从“react dom”导入react dom;
从“md5”导入md5;
导入“/styles.css”;
函数App(){
const[images,setImages]=useState([{md5Hash:null},{md5Hash:null}]);
函数onFileSelect(事件、索引){
console.log(“onfleleselect…”);
generateHashAndSave(event.target.files[0],索引);
}
函数generateHashAndSave(文件、索引){
log(“生成哈希…”);
const reader=new FileReader();
reader.onload=事件=>{
setImages(prevState=>{
const aux=Array.from(prevState);
aux[index].md5Hash=md5(event.target.result);
返回aux;
});
};
reader.readAsArrayBuffer(文件);
}
const inputItems=images.map((项目,索引)=>(
onFileSelect(事件、索引)}
accept=“.jpg、.jpeg、.png、.gif”
/>
));
返回(
{inputItems}
文件1 md5Hash:{images[0].md5Hash}
文件2 md5Hash:{images[1].md5Hash}
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);

我不能100%确定发生了什么,但您使用的
md5()
库似乎有问题。如果显式地将
ArrayBuffer
实例转换为
Uint8Array
,那么事情并不奇怪:

  aux[index].md5Hash = md5(new Uint8Array(event.target.result));
为不同的图像提供不同的哈希值


有可能您的
md5()
实际上不需要
ArrayBuffer
参数,因此在这种情况下,我想这不是一个真正的“bug”。

谢谢!
md5
文档说它需要
字符串或缓冲区。你认为这就是问题所在吗?@cbdev420嗯,我不确定;我所知道的是,当您给它一个类型化数组时,它工作得很好。它给了我与您在这里发布的内容中显示的完全相同的非真正的散列值,因此我认为它在散列
ArrayBuffer
实例中的某些特定可重复字节集;我不知道怎么做,也不知道为什么;非文本数据(如图像数据)的问题在于可能存在无法识别的UTF-16序列,这可能会导致问题。我不确定。制作一个新的阵列不应该那么昂贵;它不需要分配内存,因为缓冲区已经存在。我想你是对的。关于
ArrayBuffer
的MDN文档说:您不能直接操作ArrayBuffer的内容;相反,您可以创建一个类型化数组对象或一个以特定格式表示缓冲区的DataView对象,并使用它来读写缓冲区的内容。嗯
Uint8Array
似乎可以工作,因此它是一个强有力的竞争者:)我怀疑,只要给定的类型可以工作,它就会起作用(比如,如果您遇到某种课程的运行时异常,这很重要)
  aux[index].md5Hash = md5(new Uint8Array(event.target.result));