-
-
Save georapbox/95a98b6d0435f2de29b00f68abf1ad1c to your computer and use it in GitHub Desktop.
A tiny snippet for reading files chunk by chunk in plain JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Read files chunk by chunk. | |
* | |
* @param {File} file The file object to read in chunks. | |
* @param {Object} [options={}] Options object to override defaults. | |
* @param {Number} [chunkSize= 64 * 1024] The chunk size (in bytes) to be used. Default is 64KB. | |
* @param {Boolean} [binary=false] If true chunks will be read through FileReader.readAsArrayBuffer otherwise as FileReader.readAsText. Default is `false`. | |
* @param {Function} [chunkReadCallback=()=>{}] Optional function that accepts the read chunk as its only argument. | |
* If `binary` option is set to `true`, this function will receive an instance of `ArrayBuffer`, otherwise a `String`. | |
* @param {Function} [chunkErrorCallback=()=>{}] Optional function that accepts an object of type `FileReader.error`. | |
* @param {Function} [successCallback=()=>{}] Optional function invoked as soon as the whole file has been successfully read. | |
* @returns {undefined} | |
*/ | |
function readFileInChunks(file, options = {}) { | |
const defaults = { | |
chunkSize: 64 * 1024, // bytes | |
binary: false, | |
chunkReadCallback: () => {}, | |
chunkErrorCallback: () => {}, | |
successCallback: () => {} | |
}; | |
options = { | |
...defaults, | |
...options | |
}; | |
const { binary, chunkSize, chunkReadCallback, chunkErrorCallback, successCallback } = options; | |
const fileSize = file.size; | |
let offset = 0; | |
const onLoadHandler = evt => { | |
if (evt.target.error == null) { | |
offset += binary ? evt.target.result.byteLength : evt.target.result.length; | |
chunkReadCallback(evt.target.result); | |
} else { | |
return chunkErrorCallback(evt.target.error); | |
} | |
if (offset >= fileSize) { | |
return successCallback(file); | |
} | |
readBlock(offset, chunkSize, file); | |
}; | |
const readBlock = (_offset, length, _file) => { | |
const reader = new FileReader(); | |
const blob = _file.slice(_offset, length + _offset); | |
reader.onload = onLoadHandler; | |
if (binary) { | |
reader.readAsArrayBuffer(blob); | |
} else { | |
reader.readAsText(blob); | |
} | |
}; | |
readBlock(offset, chunkSize, file); | |
} | |
export default readFileInChunks; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment