I would like to extract binary data from a binary file into a byte array. I am having difficulty getting it to work correctly.
You can see the jsFiddle here: /
The HTML:
<div ng-controller="MainCtrl" class="container">
<h1>Select text file</h1>
<input type="file" on-read-file="showContent($fileContent)" />
<div ng-if="content">
<h2>File content is:</h2>
<pre>{{ content }}</pre>
</div>
</div>
The Javascript code:
var myapp = angular.module('myapp', []);
myapp.controller('MainCtrl', function ($scope) {
$scope.showContent = function($fileContent) {
$scope.content = $fileContent;
};
});
myapp.directive('onReadFile', function ($parse) {
return {
restrict: 'A',
scope: false,
link: function(scope, element, attrs) {
var fn = $parse(attrs.onReadFile);
element.on('change', function(onChangeEvent) {
var reader = new FileReader();
reader.onload = function(onLoadEvent) {
scope.$apply(function() {
fn(scope, {$fileContent:onLoadEvent.target.result});
});
};
reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
});
}
};
});
I get a corrupted text format as shown in this:
What am I doing wrong that's causing the content to be garbled like this?
I would like to extract binary data from a binary file into a byte array. I am having difficulty getting it to work correctly.
You can see the jsFiddle here: https://jsfiddle/alexsuch/6aG4x/
The HTML:
<div ng-controller="MainCtrl" class="container">
<h1>Select text file</h1>
<input type="file" on-read-file="showContent($fileContent)" />
<div ng-if="content">
<h2>File content is:</h2>
<pre>{{ content }}</pre>
</div>
</div>
The Javascript code:
var myapp = angular.module('myapp', []);
myapp.controller('MainCtrl', function ($scope) {
$scope.showContent = function($fileContent) {
$scope.content = $fileContent;
};
});
myapp.directive('onReadFile', function ($parse) {
return {
restrict: 'A',
scope: false,
link: function(scope, element, attrs) {
var fn = $parse(attrs.onReadFile);
element.on('change', function(onChangeEvent) {
var reader = new FileReader();
reader.onload = function(onLoadEvent) {
scope.$apply(function() {
fn(scope, {$fileContent:onLoadEvent.target.result});
});
};
reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
});
}
};
});
I get a corrupted text format as shown in this:
What am I doing wrong that's causing the content to be garbled like this?
Share Improve this question edited Jun 10, 2016 at 14:36 Ilyas Berhail asked Jun 10, 2016 at 12:37 Ilyas BerhailIlyas Berhail 431 gold badge1 silver badge5 bronze badges 7- Would you like to display or save the file? Do you know in what format the file was send, buffer / base64? – chenop Commented Jun 10, 2016 at 12:44
- Maybe this one can help you: stackoverflow./questions/16245767/… – chenop Commented Jun 10, 2016 at 12:46
- What do you want to show to the user ? Binary files is a binary files, do you want to show them the bytes value ? If so then you should use a function to convert your array of bytes to an hexadecimal string – Walfrat Commented Jun 10, 2016 at 12:49
- Actually i want to get the file content and put it in JSON object and store it in mongoDB document. – Ilyas Berhail Commented Jun 10, 2016 at 12:54
- The file that i would to sent has a buffer format and not a base64 – Ilyas Berhail Commented Jun 10, 2016 at 12:56
1 Answer
Reset to default 6You say you want the file's binary content to send over JSON and store in mongoDB. The problem with your code is that you're reading the file as text, when you should be reading it as an ArrayBuffer
, which won't apply text encoding to the binary values.
ArrayBuffer
is great, but not all browsers will support sending ArrayBuffer
over JSON via XMLHttpRequest
. Especially if you know the format it needs to be in, it might be a good idea to convert it to a regular array. Luckily, we can use typed arrays in JavaScript to help that.
var myapp = angular.module('myapp', []);
myapp.controller('MainCtrl', function ($scope) {
$scope.showContent = function($fileContent) {
$scope.content = $fileContent;
};
});
myapp.directive('onReadFile', function ($parse) {
return {
restrict: 'A',
scope: false,
link: function(scope, element, attrs) {
var fn = $parse(attrs.onReadFile);
element.on('change', function(onChangeEvent) {
var reader = new FileReader();
reader.onload = function(onLoadEvent) {
var buffer = onLoadEvent.target.result;
var uint8 = new Uint8Array(buffer); // Assuming the binary format should be read in unsigned 8-byte chunks
// If you're on ES6 or polyfilling
// var result = Array.from(uint8);
// Otherwise, good old loop
var result = [];
for (var i = 0; i < uint8.length; i++) {
result.push(uint8[i]);
}
// Result is an array of numbers, each number representing one byte (from 0-255)
// On your backend, you can construct a buffer from an array of integers with the same uint8 format
scope.$apply(function() {
fn(scope, {
$fileContent: result
});
});
};
reader.readAsArrayBuffer((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
});
}
};
});
Updated fiddle: https://jsfiddle/6aG4x/796/