从JS中的文件中读取“二进制”字符?

时间:2011-11-15 13:39:37

标签: javascript html5 canvas storage

现在当我说二进制时,我的意思是ghjkl54╞←‼╝454┴而不是10101110

我想在JavaScript中加载一个tilemap,但我不想重写用Java编写的地图编辑器,它将地图导出为二进制文件。所以我想知道,如果可能的话,我该怎么做?

另外,如果不可能,我应该阅读我只有[width][height][tilenum],[[tilenum2], tilenum3],...]的tilemap结构吗?

2 个答案:

答案 0 :(得分:2)

是的,使用HTML5 File API可以读取文件的内容。请注意,并非所有浏览器都支持此功能。

使用FileReader并使用readAsBinaryString,您可以获得这些字符:http://jsfiddle.net/S4mEv/3/

// bind a <input type="file">'s onchange event to a function
// (does not require jQuery, just for convenience here)
$('#file').change(function() {
    var fr = new FileReader; // create a file reader

    fr.onloadend = function() { // when reading has finished
        alert(fr.result); // alert the contents
    };

    fr.readAsBinaryString(this.files[0]); // start reading
});

答案 1 :(得分:1)

问题对我来说不是很清楚,您是否需要帮助实际将文件转换为javascript二进制字符串或读取已经是javascript二进制字符串格式的文件?如果是后者,也许我的答案可能有所帮助。

我已经在javascript中创建并使用了一个类来执行这样的操作:

//binaryString = result from readAsBinaryString
    var tileReader = new ByteReader( binaryString ), doubles = [];

        while( !tileReader.EOF() ) {
        doubles.push( tileReader.readDouble() );
        } //Read the whole file as big endian doubles

班级:

    function ByteReader( bytedata ) {
    this._data = bytedata || "";
    this._offset = 0;
    }

    ByteReader.prototype = {

        constructor: ByteReader,

        EOF: function(){
        return this._offset >= this._data.length;
        },

        tellSize: function(){
        return this._data.length;
        },

        seekTo: function( offset ){
        this._offset = offset;
        return this;
        },

        rewind: function() {
        this._offset = 0;
        return this;
        },

        readBytes: function( bytes ) {
        var s = this._data.substr( this._offset, bytes );
        this._offset += bytes;
        return s;
        },

        setByteStream: function( data ) {

            if( typeof data != "string" )
            throw new TypeError( typeof data + " must be string" );

        this._data = data;
        this._offset = 0;
        return this;
        },

        readDouble: function( littleEndian ) {
        var s = this.readBytes( 8 );
        var pow = Math.pow, sign, exponent, fraction;

            if( littleEndian )
            s = s.split("").reverse().join("");

        sign =  ( s.charCodeAt(0) & 0x80 ) >> 7;
        exponent =  ( ( s.charCodeAt(0) & 0x7F ) << 4 ) | ( ( s.charCodeAt(1) & 0xF0 ) >> 4 );
        fraction =  ( ( s.charCodeAt(1) & 0x0F ) * pow(2, 48) ) +
                s.charCodeAt(2) * pow( 2, 40 ) +
                s.charCodeAt(3) * pow( 2, 32 ) +
                ( ( s.charCodeAt(4) & 0xFF ) << 24 ) +
                ( ( s.charCodeAt(5) & 0xFF ) << 16 ) +
                ( ( s.charCodeAt(6) & 0xFF ) << 8  ) +
                s.charCodeAt(7);

        sign = pow( -1, sign );

            if( exponent === 2047 ) {
                if( f !== 0)
                return Number.NaN;

                else if( sign < 0 )
                return -Infinity;

                else
                return Infinity;
            }
            else if( exponent > 0 )
            return sign * Math.pow( 2, exponent - 1023 ) * ( fraction / 0x10000000000000 + 1 );


            else if ( fraction !== 0 )
            return sign * Math.pow( 2, -1022 ) * ( fraction / 0x10000000000000 );


            else 
            return 0;

        },

        readSingle: function( littleEndian ) {
        var s = this.readBytes( 4 )
        var sign, exponent, fraction;

            if( littleEndian )
            s = s.split("").reverse().join("");

        sign =  ( s.charCodeAt(0) & 0x80 ) >> 7;
        exponent =  ( ( s.charCodeAt(0) & 0x7F ) << 1 )  | ( ( s.charCodeAt(1) & 0x80 ) >> 7 );
        fraction =  ( ( s.charCodeAt(1) & 0x7F ) << 16 ) |
                ( ( s.charCodeAt(2) & 0xFF ) << 8 )  |
                ( s.charCodeAt(3) & 0xFF );

        sign = Math.pow( -1, sign );

            if( exponent === 255 ) {

                if( fraction !== 0 )
                return Number.Nan;

                else if( sign < 0 )
                return -Infinity;

                else
                return Infinity;
            }
            else if( exponent > 0 )
            return sign * Math.pow(2, exponent - 127) * ( fraction / 0x800000 + 1 );

            else if ( fraction !== 0 )
            return sign *  Math.pow(2, -126) * ( fraction / 0x800000 );

            else
            return 0;

        },

        readSByte: function() {
        var s = this.readBytes( 1 ).charCodeAt( 0 ) & 0xFF;
        return ( s ^ 0x80 ) - 0x80;
        },

        readUByte: function() {
        return this.readBytes( 1 ).charCodeAt( 0 ) & 0xFF;
        },

        readUShort: function( littleEndian ) {
        var s = this.readBytes( 2 );

            if( littleEndian )
            return ( s.charCodeAt( 0 ) & 0xFF ) |
            ( ( s.charCodeAt( 1 ) & 0xFF) << 8 );

            else
            return ( s.charCodeAt( 1 ) & 0xFF ) |
            ( ( s.charCodeAt( 0 ) & 0xFF) << 8 );
        },

        readULong: function( littleEndian ) {
        var s = this.readBytes( 4 ), r;

            if( littleEndian ) 
            r = ( s.charCodeAt( 0 ) & 0xFF )        |
            ( ( s.charCodeAt( 1 ) & 0xFF ) << 8 )   |
            ( ( s.charCodeAt( 2 ) & 0xFF ) << 16 )  |
            ( ( s.charCodeAt( 3 ) & 0xFF ) << 24 );

            else
            r = ( s.charCodeAt( 3 ) & 0xFF )        |
            ( ( s.charCodeAt( 2 ) & 0xFF ) << 8 )   |
            ( ( s.charCodeAt( 1 ) & 0xFF ) << 16 )  |
            ( ( s.charCodeAt( 0 ) & 0xFF ) << 24 );

            if ( r & 0x80000000 )
            r = ( r & 0x7FFFFFFF ) + 0x80000000;

        return r;
        },

        readSShort: function( littleEndian ){
        var s = this.readBytes( 2 ), r;

            if( littleEndian )
            r = ( s.charCodeAt( 0 ) & 0xFF ) |
            ( ( s.charCodeAt( 1 ) & 0xFF) << 8 );

            else
            r = ( s.charCodeAt( 1 ) & 0xFF ) |
            ( ( s.charCodeAt( 0 ) & 0xFF) << 8 );

        return ( r ^ 0x8000 ) - 0x8000;
        },

        readSLong: function( littleEndian ){
        var s = this.readBytes( 4 ), r;

            if( littleEndian ) 
            return ( s.charCodeAt( 0 ) & 0xFF ) |
            ( ( s.charCodeAt( 1 ) & 0xFF ) << 8 )   |
            ( ( s.charCodeAt( 2 ) & 0xFF ) << 16 )  |
            ( ( s.charCodeAt( 3 ) & 0xFF ) << 24 );

            else
            return ( s.charCodeAt( 3 ) & 0xFF ) |
            ( ( s.charCodeAt( 2 ) & 0xFF ) << 8 )   |
            ( ( s.charCodeAt( 1 ) & 0xFF ) << 16 )  |
            ( ( s.charCodeAt( 0 ) & 0xFF ) << 24 );

        }


    };

已经使用.wav文件进行了大量测试。