Javascript FileReader 读取文件不正确

Posted

技术标签:

【中文标题】Javascript FileReader 读取文件不正确【英文标题】:Javascript FileReader reads file incorrectly 【发布时间】:2017-09-18 22:21:00 【问题描述】:

我有一个简短的 javascript 函数,它将获取上传的文件并显示它的十六进制等效项。比较原始文件和十六进制编辑器中的输出表明它们部分不同但不完全不同。

String.prototype.hexEncode = function()
  var hex, i;

  var result = "";
  for (i = 0; i < this.length; i++) 
    hex = this.charCodeAt(i).toString(16);
    result += ("" + hex).slice(-4);
  

  return result


function upload() 
  var file = document.getElementById("fileToUpload").files[0];
  var reader = new FileReader();
  reader.readAsText(file, "windows-1252");
  reader.onload = function (evt) 
    var program = evt.target.result.hexEncode();
    program = program;
    console.log(program);
  

这里是原始文件和彼此相邻的输出:

2A 2A 54 49 38 33 46 2A 1A 0A 0A 43 72 65 61 74
2A 2A 54 49 38 33 46 2A 1A AA 43 72 65 61 74 65

导致输出差异的原因是什么?任何帮助将不胜感激。

【问题讨论】:

.readAsText 可能会改变内容,你试过用.readAsArrayBuffer 代替吗? 绝对不要尝试从 readAsText 结果生成十六进制转储。此外,使用非默认编码。 readAsArrayBuffer 是你想要的。 预期结果是什么? 输入输出完全相同。 【参考方案1】:

要在 js 中生成十六进制转储,您不会想使用 readAsText 方法,该方法会将您的数据转换为 UCS-2 或 UTF-16,而是直接读取您将获得的二进制数据来自readAsArrayBuffer 方法,然后从那里开始工作:

function hexDump(file) 
  return new Promise((res, rej) => 
    if (!(file instanceof Blob)) rej('wrong input');
    const reader = new FileReader();
    reader.onload = e => 
      res(hex(reader.result));
    ;
    reader.onerror = e => rej('error while reading');
    reader.readAsArrayBuffer(file);
  );
  // gotten from https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#Example
  function hex(buffer) 
    const hexCodes = [];
    const view = new DataView(buffer);
    for (let i = 0; i < view.byteLength; i += 4) 
      // Using getUint32 reduces the number of iterations needed (we process 4 bytes each time)
      let value = view.getUint32(i)
      // toString(16) will give the hex representation of the number without padding
      let stringValue = value.toString(16)
      // We use concatenation and slice for padding
      let padding = '00000000'
      let paddedValue = (padding + stringValue).slice(-padding.length).toUpperCase();
      hexCodes.push( // simple prettyfying
        paddedValue.slice(0,2),
        paddedValue.slice(2,4),
        paddedValue.slice(4,6),
        paddedValue.slice(6,8)
        );
    
    return hexCodes.join(' ');
  


// How to use it
inp.onchange = e => hexDump(inp.files[0].slice(0, 100)) // for demo I slice the file
    .then(hex => console.log(hex))
    .catch(e => console.error(e));
&lt;input type="file" id="inp"&gt;

【讨论】:

以上是关于Javascript FileReader 读取文件不正确的主要内容,如果未能解决你的问题,请参考以下文章

Javascript FileReader 读取文件不正确

使用FileReader在Javascript中同步读取多个文件

使用 Javascript FileReader API 一次读取多个文件

使用原生 Chrome Javascript/FileReader/DataView 读取 id3 v2.4 标签

JavaScript 之 FileReader简介以及原生uniapp如何将文件转成base64编码字符串示例

JavaScript 之 FileReader简介以及原生uniappvue如何将文件转成base64编码字符串示例