使用angularjs以字节数组提取二进制文件内容

时间:2016-06-10 12:37:15

标签: javascript angularjs mongodb angularjs-directive binaryfiles

我想将二进制文件中的二进制数据提取到字节数组中。我很难让它正常工作。

你可以在这里看到jsFiddle:https://jsfiddle.net/alexsuch/6aG4x/

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>

Javascript代码:

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]);
            });
        }
    };
});

我收到了损坏的文字格式,如下所示:enter image description here

我做错了什么导致内容像这样乱码?

1 个答案:

答案 0 :(得分:5)

您说您希望文件的二进制内容通过JSON发送并存储在mongoDB中。代码的问题在于,当您将文件作为ArrayBuffer读取时,您将文件作为文本读取,而不会将文本编码应用于二进制值。

ArrayBuffer很棒,但并非所有浏览器都支持通过ArrayBuffer通过JSON发送XMLHttpRequest。特别是如果您知道它需要的格式,将它转换为常规数组可能是个好主意。幸运的是,我们可以在JavaScript中使用类型化数组来帮助实现这一点。

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]);
            });
        }
    };
});

更新了小提琴:https://jsfiddle.net/6aG4x/796/