0

Here's the simple code:

document.querySelector('#upload').addEventListener('change', async (e) => {
  const initialFile = e.target.files[0];
  const arrayBuffer = await initialFile.arrayBuffer();

  const text = await initialFile.text();
  var enc = new TextEncoder();
  const arrayBufferFromText = enc.encode(text).buffer

  // WHY THESE TWO AREN'T THE SAME?
  console.log(arrayBuffer.byteLength)
  console.log(arrayBufferFromText.byteLength);
})
<input type="file" id="upload">

When uploading a binary file, e.g. an image, arrayBuffer will be different from arrayBufferFromText. That's apparently happening somewhere in the text -> buffer conversion using TextEncoder.

Why is this happening and how to get arrayBufferFromText the same as arrayBuffer?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Limon Monte
  • 52,539
  • 45
  • 182
  • 213
  • 3
    `text()` interprets the input as UTF-8. If the input is not actually UTF-8 you will either get an error or some replacement characters (depending on which APIs are used). In other words: treating arbitrary binary data as UTF-8 is not a reliably reversable operation (it *can* be in some cases, but if it's truly binary data that is quite rare). How do you fix this? Don't use `text()` if the input is not known to be text. – Joachim Sauer Jun 07 '22 at 08:57
  • Thank you for the reply @Joachim Sauer. Did I understand correctly that `text()` will create an invalid result that can't be converted back to the original binary `File` or buffer? – Limon Monte Jun 07 '22 at 09:08
  • Yes, that's extremely likely to happen when trying to interpret binary data as text, and especially when using UTF-8 for that. If you don't know what the data is, then you should always treat it as binary, that's the safe bet. – Joachim Sauer Jun 07 '22 at 09:10
  • 1
    Do it the other way round: `await file.text()` should have the same result as `new TextDecoder().decode(await file.arrayBuffer())`. But as Joachim said, text is not a (good, if at all) representation of binary data. – Bergi Jun 07 '22 at 11:05
  • @JoachimSauer You might want to post that as an answer – Bergi Jun 07 '22 at 11:05
  • Thank you both for the prompt answers! @JoachimSauer please post your answer, I'll accept it. – Limon Monte Jun 07 '22 at 11:24

0 Answers0