Html5 File API Read as Text and Binary

HTML5 File API read as text and binary

2022 update: See explanation below for why the OP was seeing what they were seeing, but the code there is outdated. In modern environments, you'd use the methods on the Blob interface (which File inherits):

  • arrayBuffer for reading binary data (which you can then access via any of the typed arrays)
  • text to read textual data
  • stream for getting a ReadableStream for handling data via streaming (which allows you to do multiple transformations on the data without making multiple passes through it and/or use the data without having to keep all of it in memory

Once you have the file from the file input (const file = fileInput.files[0] or similar), it's literally just a matter of:

await file.text(); // To read its text
// or
await file.arrayBuffer(); // To read its contents into an array buffer

(See ReadableStream for an example of streams.)

You might access the array buffer via a Uint8Array (new Uint8Array(buffer)).

Here's an example of text and arrayBuffer:

const $ = id => document.getElementById(id);

const fileInput = $("fileInput");
const btnRead = $("btnRead");
const rdoText = $("rdoText");
const contentsDiv = $("contents");

const updateButton = () => {
btnRead.disabled = fileInput.files.length === 0;
};

const readTextFile = async (file) => {
const text = await file.text();
contentsDiv.textContent = text;
contentsDiv.classList.add("text");
contentsDiv.classList.remove("binary");
console.log("Done reading text file");
};

const readBinaryFile = async (file) => {
// Read into an array buffer, create
const buffer = await file.arrayBuffer();
// Get a byte array for that buffer
const bytes = new Uint8Array(buffer);
// Show it as hex text
const lines = [];
let line = [];
bytes.forEach((byte, index) => {
const hex = byte.toString(16).padStart(2, "0");
line.push(hex);
if (index % 16 === 15) {
lines.push(line.join(" "));
line = [];
}
});
contentsDiv.textContent = lines.join("\n");
contentsDiv.classList.add("binary");
contentsDiv.classList.remove("text");
console.log(`Done reading binary file (length: ${bytes.length})`);
};

updateButton();

fileInput.addEventListener("input", updateButton);

btnRead.addEventListener("click", () => {
const file = fileInput.files[0];
if (!file) {
return;
}
const readFile = rdoText.checked ? readTextFile : readBinaryFile;
readFile(fileInput.files[0])
.catch(error => {
console.error(`Error reading file:`, error);
});
});
body {
font-family: sans-serif;
}
#contents {
font-family: monospace;
white-space: pre;
}
<form>
<div>
<label>
<span>File:</span>
<input type="file" id="fileInput">
</label>
</div>
<div>
<label>
<input id="rdoText" type="radio" name="format" value="text" checked>
Text
</label>
<label>
<input id="rdoBinary" type="radio" name="format" value="binary">
Binary
</label>
</div>
<div>
<input id="btnRead" type="button" value="Read File">
</div>
</form>
<div id="contents"></div>

HTML5 File API readAsBinaryString reads files as much larger, different than files on disk

This is probably because you're reading the file as a binary string and constructing the multipart/form-data request manually. For one, you don't need to use FileReader.
Since you just want to send the content, try using xhr.send(File) or xhr.send(FormData). The latter constructs and sends a multipart/form-data for you:

function uploadFiles(url, files) {
var formData = new FormData();

for (var i = 0, file; file = files[i]; ++i) {
formData.append(file.name, file);
}

var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = function(e) { ... };

xhr.send(formData); // multipart/form-data
}

document.querySelector('input[type="file"]').onchange = function(e) {
uploadFiles('/server', this.files);
};

HTML5 Binary File Writing w/ Base64

I wrote an extension that captures a screenshot using Chrome, puts it on a canvas, resizes it, then saves the canvas data using the Filesystem API. Not sure if this is directly similar to yours, but perhaps most of the code will suffice?

In this case, I assume my dataURI (eg myCanvas.toDataURL("image/png")) would be the same Base64 format as your dataInBase64Format.

Function:

// canvas.toBlob is not implemented in Chrome yet! So we have to build the blob ourselves.
// Derived from http://mustachified.com/master.js
// via http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2011-April/031243.html
// via https://bugs.webkit.org/show_bug.cgi?id=51652
// via http://code.google.com/p/chromium/issues/detail?id=67587

function dataURItoBlob(dataURI, callback) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs
var byteString = atob(dataURI.split(',')[1]);

// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}

// write the ArrayBuffer to a blob, and you're done
var bb = new window.WebKitBlobBuilder();
bb.append(ab);
return bb.getBlob(mimeString);
}

Usage:

// Save image data
function onInitFs(fs){
fs.root.getFile(fileName, {create:true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.write(dataURItoBlob(myCanvas.toDataURL("image/png")));
}, fileErrorHandler);
}, fileErrorHandler);
}, fileErrorHandler);

Saving binary data as file using JavaScript from a browser

This is possible if the browser supports the download property in anchor elements.

var sampleBytes = new Int8Array(4096);

var saveByteArray = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, name) {
var blob = new Blob(data, {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());

saveByteArray([sampleBytes], 'example.txt');



JSFiddle: http://jsfiddle.net/VB59f/2

html5 fileReader -- how to only read the first N characters of a file?

You can use the .slice method. You can read more here

var reader = new FileReader();

reader.onloadend = function(evt)
{
if (evt.target.readyState == FileReader.DONE) // DONE == 2
{
alert(evt.target.result);
}
};

var blob = file.slice(start, stop + 1);
reader.readAsBinaryString(blob);

how to read a text file using javascript without using activeX?

we can do that using HTML5 fileAPI - FileReader.ReadAsText

HTML5 File API read as text and binary



Related Topics



Leave a reply



Submit