Javascript filereader onload ( get file from server ) - javascript

What I want is to read a file from the windows file system or a server so I can display the contents on the website and we are not allowed to use a database or PHP only Javascript.
What I currently have is beneath this and it works if I get the file from a html file upload box the only thing I need is how do I get a file in the javascript without inserting it manually but to load on pageload.
The rest of the code works if I insert the file manually I only need to get a file and insert it into var file = ;
var file = // How do I get file from windows system / or server is also a possibility
var reader = new FileReader();
reader.onload = function(progressEvent){
// Entire file
console.log(this.result);
// By lines
var lines = this.result.split('\n');
for(var line = 0; line < lines.length; line++){
console.log(lines[line]);
}
};
reader.readAsText(file);

I got it to work
var file = readTextFile("test.txt");
var allText;
var trumpCount = 0;
var hilaryCount = 0;
var reader = new FileReader();
// Entire file
console.log(this.result);
// alert(allText);
// By lines
var lines = allText.split('\n');
for(var line = 0; line < lines.length; line++){
// alert(lines[line]);
if (lines[line].indexOf("t") !== -1){
trumpCount++;
}else{
hilaryCount++;
}
}
alert("Votes for trump: " + trumpCount + " Votes for hilary: " + hilaryCount + " Total votes: " + (trumpCount + hilaryCount))
function readTextFile(file)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
allText = rawFile.responseText;
//alert(allText);
}
}
}
rawFile.send(null);
}

Related

Multifile upload as chunks

I'm setting up multi file upload in client-side.Below are the steps, I need to done:
User will upload multiple files at once. Ex: 5 files at a time.
Each file size is vary and large files. Ex: File1.size = 800mb
Slice that large files into chunks. Ex: chunk_size = 50mb
Each chunk will be send to backend and will get response from it.
I'm able to do it for single file upload, like splicing large file chunks.But I'm unable to do it for multiple files uploaded at a time.
Below is the code I tried:
var that = this;
var files = that.files || [];
var url = that.config.url;
var fileKeyUpload = that.config.fileKeyUpload;
for(var i=0; i < files.length; i++) { //multiple files loop
var start = 0; //chunk start as 0
var bytes_per_chunk = 52428800; // 50 MB per chunk
var blob = files[i];
var size = blob.size;
var end = bytes_per_chunk;
var getStatus = function() {
var nextChunk = start + bytes_per_chunk;
var percentage = nextChunk > size ? 100 : Math.round((start / size) * 100); // calculating percentage
uploadFile(blob.slice(start, end), files[key], start, percentage).then(function() {
if(start < size && bytes_per_chunk < size){
start = end;
end = start + bytes_per_chunk;
start < size ? getStatus() : null;
}
});
}
return getStatus();
}
function uploadFile(blob, file, offset, completedPrecentile) {
return new Promise(function(resolve) {
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader("Accept", "*/*");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
if(that.config.hasOwnProperty("onFileUploadComplete")){
that.config.onFileUploadComplete(xhr, true, completedPrecentile, file);
resolve();
}
}
};
xhr.send(blob);
});
};
This is what I tried, it works for single file, Any help on how to achieve multiple file upload with slicing large files into chunks.
Unable to post working demo since local api is used.

How to pass different types of data on ajax send() function to PHP?

I am trying to send a file(pdf file) as well as user text input using ajax using vanilla javascript please dont post any jquery answers.
formData contains the pdf file and formVal contains the user text input.
If I remove formVal from the request.send function then the file is uploaded but if I include formVal the send function does not work as nothing gets uploaded.
var formData = new FormData();
var dropzone = document.getElementById('dropzone');
var sub = document.getElementById('subForm');
var uploadFile = function (formVal) {
var request = new XMLHttpRequest();
request.onload = function(){
var data = this.responseText;
console.log(data);
//window.location.reload();
}
request.open('post', 'index.php');
request.send(formData, formVal);
}
dropzone.ondrop = function (event) {
event.preventDefault();
document.getElementById('para1').innerHTML = "File uploaded";
var files = event.dataTransfer.files;
//uploadFile(event.dataTransfer.files,);
var i;
for(i = 0; i<files.length; i = i+1){
formData.append('file[]', files[i]);
}
return false;
}
sub.onclick = function () {
var code = document.getElementById('cCode').value;
var size = document.getElementById('cSize').value;
var dd = document.getElementById('cDD').value;
var val = "c=" +code+"&s="+size+"&d="+dd;
if(formData.get('file[]') === null){
alert("Drang and drop PDF file");
}else{
uploadFile(val);
}
}

How to log contents of HTML5 drag and drop file that is 60MB+ without hanging for minutes?

I have a file that i want to drop on a page and read file contents. its a CSV with 9 columns. My drop command outputs file contents like this:
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.files[0];
var fileReader = new FileReader();
fileReader.onload = function (e) {
console.log(fileReader.result)
};
fileReader.onerror = function (e) {
throw 'Error reading CSV file';
};
// Start reading file
fileReader.readAsText(data);
return false;
}
When I drag and drop a simple file that is a couple kilobytes or 1MB, I can see the output of the contents of the file. However given a large CSV file, it takes many many minutes before it shows up. Is there a way to make it so that there is some streaming maybe where it does not look like its hanging?
With Screw-FileReader
You can get a ReadableStream and do it in a streaming fashion
'use strict'
var blob = new Blob(['111,222,333\naaa,bbb,ccc']) // simulate a file
var stream = blob.stream()
var reader = stream.getReader()
var headerString = ''
var forEachLine = function(row) {
var colums = row.split(',')
// append to DOM
console.log(colums)
}
var pump = function() {
return reader.read().then(function(result) {
var value = result.value
var done = result.done
if (done) {
// Do the last line
headerString && forEachLine(headerString)
return
}
for (var i = 0; i < value.length; i++) {
// Get the character for the current iteration
var char = String.fromCharCode(value[i])
// Check if the char is a new line
if (char.match(/[^\r\n]+/g) !== null) {
// Not a new line so lets append it to
// our header string and keep processing
headerString += char
} else {
// We found a new line character
forEachLine(headerString)
headerString = ''
}
}
return pump()
})
}
pump().then(function() {
console.log('done reading the csv')
})
<script src="https://cdn.rawgit.com/jimmywarting/Screw-FileReader/master/index.js"></script>
If you prefer using the old FileReader without dependencies, pipe's and transform
'use strict'
var blob = new Blob(['111,222,333\naaa,bbb,ccc']) // simulate a file
var fr = new FileReader()
var headerString = ''
var position = 0
var forEachLine = function forEachLine(row) {
var colums = row.split(',')
// append to DOM
console.log(colums)
}
var pump = function pump() {
return new Promise(function(resolve) {
var chunk = blob.slice(position, position + 524288)
position += 524288
fr.onload = function() {
var value = fr.result
var done = position >= blob.size
for (var i = 0; i < value.length; i++) {
var char = value[i]
// Check if the char is a new line
if (char.match(/[^\r\n]+/g) !== null) {
// Not a new line so lets append it to
// our header string and keep processing
headerString += char
} else {
// We found a new line character
forEachLine(headerString)
headerString = ''
}
}
if (done) {
// Send the last line
forEachLine(headerString)
return resolve() // done
}
return resolve(pump())
}
// Read the next chunk
fr.readAsText(chunk)
})
}
pump().then(function() {
console.log('done reading the csv')
})

Read File byte for byte and parse to int

I have to read data from an file. This data was written by an server byte-wise into the file. The file has an fix structure, now I want to read the Information in it with JS.
I have found http://www.html5rocks.com/en/tutorials/file/dndfiles/ and copied it down to fiddle: http://jsfiddle.net/egLof4ph/
function readBlob(opt_startByte, opt_stopByte) {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onloadend = function(evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
document.getElementById('byte_content').textContent = evt.target.result;
document.getElementById('byte_range').textContent = ['Read bytes: ', start + 1, ' - ', stop + 1,
' of ', file.size, ' byte file'].join('');
}
};
var blob = file.slice(start, stop);
var a = reader.readAsBinaryString(blob);
}
document.querySelector('.readBytesButtons').addEventListener('click', function(evt) {
if (evt.target.tagName.toLowerCase() == 'button') {
var startByte = evt.target.getAttribute('data-startbyte');
var endByte = evt.target.getAttribute('data-endbyte');
readBlob(startByte, endByte);
}
}, false);
I knew that the first 7 Bytes are crap and can throw them away. The next 68Bytes belong together and every value is 4bytes big. After the 68Bytes again 68 usable bytes come (that 68bytes are "timeslots").
My Question:
When I am using that Code I get many signs (A, Q, &&&, special chars,..), but the data are in reality longs. How can I parse them into Numbers? According to the Filereader API readAsBinarsString() returns raw binary data. And how to correctly parse the whole File?
So, the original File looks like this:
<7B>Metadata</7B><4B>long value</4B>....17times for each timeslot <4B>long value</4B>....17times again.... and this util the end of the file.
When I am using the above Code I get output like: �&�&WK��
Furthermore I have found: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays (since FileReader provides an method which returns an ArrayBuffer), so I guess I should use readAsArrayBuffer(), but how to use it to get to my data?
You really need binary ?
Note that readAsBinaryString method is now deprecated as per the 12 July 2012 Working Draft from the W3C.
function readBlob(opt_startByte, opt_stopByte) {
var files = document.getElementById('files').files;
if (!files.length) {
alert('Please select a file!');
return;
}
var file = files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
reader.onloadend = function (evt) {
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
var a = new Uint8Array(evt.target.result)
var binary = ""
for (var i =0; i <= a.length; i++) {
binary += Number(a[i]).toString(2)
}
document.getElementById('byte_content').textContent = binary;
document.getElementById('byte_range').textContent = ['Read bytes: ', start + 1, ' - ', stop + 1,
' of ', file.size, ' byte file'].join('');
}
};;
var blob = file.slice(start, stop);
var a = reader.readAsArrayBuffer(blob)
}
document.querySelector('.readBytesButtons').addEventListener('click', function (evt) {
if (evt.target.tagName.toLowerCase() == 'button') {
var startByte = evt.target.getAttribute('data-startbyte');
var endByte = evt.target.getAttribute('data-endbyte');
readBlob(startByte, endByte);
}
}, false);

Asynchronous execution in javascript any solution to control execution?

I need a solution to control code execution in javascript.I want code on next line should not be executed unless the code on current line is completely executed.
Is there any solution?
function handleFileSelect(evt) {
var files = evt.target.files;
for (var i = 0; i < files.length; i++) {
alert("for");
f = files[i];
fileExtension = f.name.split('.').pop();
if(fileExtension != 'kml' && fileExtension !='kmz' && fileExtension != 'csv'){
alert('Unsupported file type ' + f.type + '(' + fileExtension + ')');
return;
}
var fileReaderkmlcsv = new FileReader();
fileReaderkmlcsv.onloadend = loadend;
fileReaderkmlcsv.onerror = function(event) {
alert("ERROR: " + event.target.error.code);
};
fileReaderkmlcsv.readAsText(f);
} //- end for
} //handleFileSelect
function loadend(theFile) {
alert("loadend");
//code for processing my files
}
The issue is that loadend is running as soon as any one of the FileReaders has completed loading. You'll need to redesign the code to wait for all 3 of them to finish, something like:
function handleFileSelect(evt) {
var files = evt.target.files;
var fileReaders = [];
var loadCount = 0;
for (var i = 0; i < files.length; i++) {
f = files[i];
fileExtension = f.name.split('.').pop();
if(fileExtension != 'kml' && fileExtension !='kmz' && fileExtension != 'csv'){
alert('Unsupported file type ' + f.type + '(' + fileExtension + ')');
return;
}
function fileLoaded() {
loadCount++;
//Check if we've loaded all the files
if (loadCount == files.length) {
loadend(fileReaders);
}
}
var fileReaderkmlcsv = new FileReader();
fileReaderkmlcsv.onloadend = fileLoaded;
fileReaderkmlcsv.onerror = function(event) {
alert("ERROR: " + event.target.error.code);
};
fileReaderkmlcsv.readAsText(f);
fileReaders.push(fileReaderkmlcsv);
}
}
function loadend(files) {
//files now contains an array of completed FileReader objects
}
Note that I don't have direct experience of the FileReader object itself - if onloadend doesn't fire if an error occurs, you'll need to put similar logic in the onerror event as well to make sure that the loadCount variable still gets incremented/checked etc.

Categories

Resources