repeative partial reads using html5 file APIs - javascript

I do NOT want to read the ENTIRE contents of a file into memory; only parts of it, and only on demand.
Yet, It seems I can read a chunk ONLY ONCE (using a file.slice()), while all following reads return zero-length. Any ideas?
Here is a simplified sample of the code that fails on 2nd call:
var chunkNo=0;
function readNextChunk()
{
var file=document.getElementsByTagName("input").item(0).files[0];
var blob=file.slice(100*chunkNo, 100);
var reader=new FileReader();
reader.onload=function(e) { console.log("No"+chunkNo+":\n"+reader.result);
chunkNo++;
};
reader.readAsText(blob);
}

Related

Javascript parse XLS - XLSX not defined

I have been trying to use sheetJS and follow examples that completely work in jsfiddle, however I cannot get to work when creating a new js file. I have tried multiple browswers, but keep getting the same error "XLSX is not defined"
I have tried this Excel to JSON javascript code? and wanted to ask on there but needed 50 rep to leave a comment.
Here is the code snippet and am including the following files in this order:
shim.js, jszip.js,xlsx.js
var oFileIn;
$(function() {
oFileIn = document.getElementById('xlf');
if(oFileIn.addEventListener) {
console.log("if hit")
oFileIn.addEventListener('change', filePicked, false);
}
$("#xlf").on("change",function(oEvent){
console.log("jqiey workd?")
filePicked(oEvent)
})
});
function filePicked(oEvent) {
// Get The File From The Input
var oFile = oEvent.target.files[0];
var sFilename = oFile.name;
// Create A File Reader HTML5
var reader = new FileReader();
// Ready The Event For When A File Gets Selected
reader.onload = function(e) {
var data = e.target.result;
var cfb = XLSX.read(data, {type: 'binary'});
console.log(cfb)
cfb.SheetNames.forEach(function(sheetName) {
// Obtain The Current Row As CSV
var sCSV = XLS.utils.make_csv(cfb.Sheets[sheetName]);
var oJS = XLS.utils.sheet_to_json(cfb.Sheets[sheetName]);
$("#my_file_output").html(sCSV);
console.log(oJS)
$scope.oJS = oJS
});
};
I have tried numerous examples, this is just the only one I came across that worked on jsfiddle. The same error occurs if it is XLS or XLSX...
In other examples such as the one provided by sheetJS it has
var X = XLSX;
right under the script segment, and will automatically get error that XLSX is not defined on that line.
Anyone come across this, or know what the issue is?
-Thanks!!!
The included files with the project weren't correct. The project had a corrupt js file. I fixed it by manually adding all sheet project download folder and replacing files.

Javascript new File() gem file size

I have the following file structure:
test.html
test.json
And the following JS function:
function get_file(){
var app_path = app.activeDocument.path,
file = new File(app_path + '/test.json');
console.log(file);
}
How can I make the function log the file's content?
I'm not sure if everything you can do in the browsers environment translates to everything you can do in photoshops environment. But you should look at a few things.
Doing This in the Browser
The File object.
https://developer.mozilla.org/en-US/docs/Web/API/File
Notable that it extends the Blob object.
https://developer.mozilla.org/en-US/docs/Web/API/Blob
Which if you researched you would find it can be read using the FileReader.
https://developer.mozilla.org/en-US/docs/Web/API/FileReader
So this would work in the browser but may/may-not work in the photoshop scripting set.
function get_file(){
var app_path = app.activeDocument.path,
file = new File(app_path + '/test.json');
var reader = new FileReader();
reader.onloadend = function() {
console.log(reader.result);
}
reader.readAsText(file);
}
This is asynchronous so you may need to use a callback depending on what you're trying to do with this. You won't be able to return the string from inside the reader.onloadend event.
Doing This in Photoshop
Take a look at their scripting references. Specifically the javascript reference.
All Resources: http://www.adobe.com/devnet/photoshop/scripting.html
Javascript PDF: http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/photoshop/pdfs/photoshop-cc-javascript-ref-2015.pdf
It looks like they don't have the FileReader but instead the File object can be used to read content. The File API begins on page 109 but it's empty! The documentation is a bit pathetic so I can see why you'd have trouble finding this. With some searching I found someone doing this in 2012 (but I don't know if it will still work- worth a shot)
var b = new File("c:\test.txt");
b.open('r');
var str = "";
while(!b.eof) {
str += b.readln();
}
b.close();
alert(str);
Let me know if that works.

playing html5 video from in memory source

I am retrieving multiple encrypted data with the help of some ajax queries, and performing some manipulation to transform all theses encrypted chunks into a valid video. And now that I have the binary of the video in memory, I am stuck. How can I display it ?
Just to be sure, I have replicated all theses steps on the server side, and the final output is really a playable video. So my only problem is to display my javascript binary object as a video.
I am doing my best to use only web technologies (html5, video tag, javascript) and I would like to avoid developing my own custom player in flash, which is my very last solution.
if you have an idea, I'm interested. For my part, I am out of imagination.
Here's a quick example that just uses a file input instead of the AJAX you'd normally be using. Note that the first input is wired up to a function that will read the file and return a dataURL for it.
However, since you don't have a fileObject, but instead have a stream of data that represents the contents of the file, you can't use this method. So, I've included a second input, which is wired up to a function that just loads the file as a binary string. This string is then base64 encoded 'manually' with a browser function, before being turned into a dataURL. To do this,you need to know what type of file you're dealing with in order to construct the URL correctly.
It's fairly slow to load even on this laptop i7 and probably sucks memory like no-one's business - mobile phones will likely fall over in a stupor (I haven't tested with one)
You should be able to get your data-stream and continue on from the point where I have the raw data (var rawResult = evt.target.result;)
Error checking is left as an exercise for the reader.
<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
// callback gets data via the .target.result field of the param passed to it.
function loadFileObject(fileObj, loadedCallback)
{
var reader = new FileReader();
reader.onload = loadedCallback;
reader.readAsDataURL( fileObj );
}
// callback gets data via the .target.result field of the param passed to it.
function loadFileAsBinary(fileObj, loadedCallback)
{
var reader = new FileReader();
reader.onload = loadedCallback;
reader.readAsBinaryString( fileObj );
}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
byId('fileInput1').addEventListener('change', onFileInput1Changed, false);
byId('fileInput2').addEventListener('change', onFileInput2Changed, false);
}
function onFileInput1Changed(evt)
{
if (this.files.length != 0)
{
var curFile = this.files[0];
loadFileObject(curFile, onVideoFileReadAsURL);
function onVideoFileReadAsURL(evt)
{
byId('vidTgt').src = evt.target.result;
byId('vidTgt').play();
}
}
}
function onFileInput2Changed(evt)
{
if (this.files.length != 0)
{
var curFile = this.files[0];
loadFileAsBinary(curFile, onVideoFileReadAsBinary);
function onVideoFileReadAsBinary(evt)
{
var rawResult = evt.target.result;
var b64Result = btoa(rawResult);
var prefaceString = "data:" + curFile.type + ";base64,";
// byId('vidTgt').src = "data:video/mp4;base64," + b64Result;
byId('vidTgt').src = prefaceString + b64Result;
byId('vidTgt').play();
}
}
}
</script>
<style>
</style>
</head>
<body>
<input type='file' id='fileInput1'/>
<input type='file' id='fileInput2'/>
<video id='vidTgt' src='vid/The Running Man.mp4'/>
</body>
</html>
To display your video you would need to get an URL for it so that you are able to pass a reference to the video element.
There is URL.createObjectURL which should provide you with such an URL to refer to your data. See https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL for further explanations and mind the compatibility table.
Mozilla hosts an example at https://developer.mozilla.org/samples/domref/file-click-demo.html which displays local files. It should be possible to adapt this to setting the video element's src property instead. Depending on how you store your data, it should be possible to play your video this way.
I tried it in Firefox for data from a File object which left me with a URL blob:https://developer.mozilla.org/ed2e4f2f-57a6-4b06-8d56-d0a1a47a9ffd that I could use to play a video.

How to get all sliced data from the entire file

I get the original code from here: Using Javascript FileReader with huge files
But my purpose is different, the author wants to get just a part of the whole but I want them all.
I'm trying modify it with loop, mixed with this technique: slice large file into chunks and upload using ajax and html5 FileReader
All fails, is there anyway I can get what I want.
var getSource = function(file) {
var reader = new FileReader();
reader.onload = function(e) {
if (e.target.readyState == FileReader.DONE) {
process(e.target.result);
}
};
var part = file.slice(0, 1024*1024);
reader.readAsBinaryString(part);
};
function process(data) {
// data processes here
}
Thank you,

Reading client side text file using Javascript

I want to read a file (on the client side) and get the content in an array. It will be just one file. I have the following and it doesn't work. 'query_list' is a textarea where I want to display the content of the file.
<input type="file" id="file" name="file" enctype="multipart/form-data"/>
<script>
document.getElementById('file').addEventListener('change', readFile, false);
function readFile (evt) {
var files = evt.target.files;
var file = files[0];
var fh = fopen(file, 0);
var str = "";
document.getElementById('query_list').textContent = str;
if(fh!=-1) {
length = flength(fh);
str = fread(fh, length);
fclose(fh);
}
document.getElementById('query_list').textContent = str;
}
</script>
How should I go about it? Eventually I want to loop over the array and run some SQL queries.
If you want to read files on the client using HTML5's FileReader, you must use Firefox, Chrome or IE 10+. If that is true, the following example reads a text file on the client.
your example attempts to use fopen that I have never heard of (on the client)
http://jsfiddle.net/k3j48zmt/
document.getElementById('file').addEventListener('change', readFile, false);
function readFile (evt) {
var files = evt.target.files;
var file = files[0];
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result);
}
reader.readAsText(file)
}
For IE<10 support you need to look into using an ActiveX Object like ADO.Stream Scripting.FileSystemObject http://msdn.microsoft.com/en-us/library/2z9ffy99(v=vs.85).aspx but you'll run into a security problem. If you run IE allowing all ActiveX objects (for your website), it should work.
There is such thing as HTML5 File API to access local files picked by user, without uploading them anywhere.
It is quite new feature, but supported by most of modern browsers.
I strongly recommend to check out this great article to see, how you can use it.
There is one problem with this, you can't read big files (~400 MB and larger) because straight forward FileAPI functions attempting to load entire file into memory.
If you need to read big files, or search something there, or navigate by line index check my LineNavigator, which allows you to read, navigate and search in files of any size. Try it in jsFiddle! It is super easy to use:
var navigator = new FileNavigator(file);
navigator.readSomeLines(0, function linesReadHandler(err, index, lines, eof, progress) {
// Some error
if (err) return;
// Process this line bucket
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
// Do something with it
}
// End of file
if (eof) return;
// Continue reading
navigator.readSomeLines(index + lines.length, linesReadHandler);
});
Well I got beat to the answer but its different:
<input type="file" id="fi" />
<button onclick="handleFile(); return false;">click</button>
function handleFile() {
var preview = document.getElementById('prv')
var file = document.getElementById('fi').files[0];
var div = document.body.appendChild(document.createElement("div"));
div.innerHTML = file.getAsText("utf-8");
}
This will work in FF 3.5 - 3.6, and that's it. FF 4 and WebKit you need to use the FileReader as mentioned by Juan Mendes.
For IE you may find a Flash solution.
I work there, but still wanted to contribute because it works well: You can use the filepicker.io read api to do exactly this. You can pass in an dom element and get the contents back, for text or binary data, even in IE8+

Categories

Resources