2017-09-18 243 views
1

我有一個簡短的JavaScript函數,它將取得一個上傳的文件並顯示相當於它的十六進制數。在十六進制編輯器中比較原始文件和輸出顯示它們部分不同但不完全。Javascript FileReader讀取文件不正確

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 

是什麼原因造成的輸出的不同?任何幫助將不勝感激。

+1

相反.readAsText'的'這可能會改變的內容,你有沒有試過['.readAsArrayBuffer'(HTTPS://developer.mozilla .org/en-US/docs/Web/API/FileReader/readAsArrayBuffer)而不是? –

+0

絕對不要嘗試從readAsText結果生成十六進制轉儲。此外與非默認編碼。 readAsArrayBuffer是你想要的。 – Kaiido

+0

預期結果是什麼? – guest271314

回答

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));
<input type="file" id="inp">

相關問題