10

I do not consider myself a programmer, so I have found many, many answers to my questions by searching this site. I have been unable to figure this one out, though.

Using Javascript (really the only language I can even attempt right now), I am trying to upload a file and load its binary data into an ArrayBuffer for editing. I am utilizing both FileSaver.js and Blob.js to increase compatibility. I have the user select the file, then load the file. When loading commences, a FileReader uses readAsArrayBuffer to load the file into an ArrayBuffer. I currently have it set to give an alert to check on the contents of the ArrayBuffer, but I will eventually remove that and simply work with the data.

If I take out the index, the alert knows that it is displaying an ArrayBuffer, but whenever I pick an index (like [0]), it tells me it's undefined. How do I get the file data into an ArrayBuffer? And how will it be divided up? Preferably I'd like 1 byte to an index.

function loadButtonPressed() {
    var loadedFile = document.getElementById('loadFile').files;
    var testFile = loadedFile[0];
    var reader = new FileReader();
    reader.onloadend = function(evt) {
        if (evt.target.readyState == FileReader.DONE) {
            alert(String(reader.result[0]));
        }
    };
    reader.readAsArrayBuffer(testFile);
}

2 Answers 2

14

To be able to access an ArrayBuffer's data, you need to create a View from it.

This can be done in two ways:

TypedArrays
These are array like objects, each byte of your ArrayBuffer will be represented in the chosen TypedArray type. Note that this will use the system's endianness.

var buf = new TextEncoder().encode('Hello world').buffer;
console.log(buf);
// create an Uint8 view
var view = new Uint8Array(buf);
console.log(view);
// now you can iterate and modify your arrayBuffer from this view.
view[0] = 23;

console.log(new Uint8Array(buf)[0]);

DataView.
This is slower but gets more options to get and set data in your ArrayBuffer. E.g, you can set the endianness, you don't need to check the byteLength of your buffer to get Int32 values etc.

var buf = new TextEncoder().encode('Hello world').buffer;
console.log(buf);
// create a dataView
var view = new DataView(buf);
console.log(view.getUint8(0));
// now you can iterate and modify your arrayBuffer from this view.
view.setUint8(0, 23);

console.log(new Uint8Array(buf)[0]);

Note: Both methods will directly modify the ArrayBuffer's data, and its data will not be cloned.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your in-depth explanation!
6

A buffer is just a series of bytes with no meaning. JS provides no way to directly manipulate a buffer. To look into a buffer, you need a view, that defines how the buffer is interpreted - either a typed array, or a DataView object. Try this:

// ...
let buffer = reader.result;
let view = Int8Array(buffer);
console.log(view[0]);

or this:

// ...
let buffer = reader.result;
console.log(new DataView(buffer).getInt8(0))

2 Comments

Remember that readAsArrayBuffer is async and returns void. The view must be created inside (or following) the handler.
Thank you! It's nice to know the answer is so simple.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.