1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | function uints(reader,offset,length){ if(offset===null) offset = reader.__pos; else reader.__pos = Number(offset); reader.__pos += fs.readSync(reader.__fileSign,reader.__buffer,0,length,offset); return reader.__le? reader.__buffer.readUIntLE(0,length): reader.__buffer.readUIntBE(0,length); } FileReader = class { constructor(file,little=true){ this.__fileSign = fs.openSync(file); this.__buffer = Buffer.alloc(8) this.__le = Boolean(little); this.__pos = 0; this.__bigPos = false; //用於標示偏移是否改採用 BigInt,需要先驗證偏移是否可以使用 BigInt 正確定位 this.__ss = fs.statSync(file); } set little(v){ this.__le = Boolean(v) } writeTo(file, offset, length=null){ if(length===null) throw new Error('length required'); if(offset===null) throw new Error('offset required'); offset = Number(offset); if(length<0) length = this.__ss.size - offset; var wf = fs.openSync(file,'w'); var buffer = Buffer.alloc(16384); //16KB var readed = 0; var remaining = length; while(remaining){ readed = fs.readSync( this.__fileSign, buffer, 0, Math.min(16384,remaining), offset ); fs.writeSync(wf,buffer,0,readed); remaining -= readed; offset += readed; } fs.close(wf); } read(buffer, offset=null, length=null){ if(length===null) length = buffer.length; if(offset===null) offset = this.__pos; else this.__pos = Number(offset); var readed = fs.readSync(this.__fileSign,buffer,0,length,offset); this.__pos += readed; return readed; } string(offset=null,length,encode){ if(length===null) throw new Error('length required'); var buffer = Buffer.alloc(length); var readed = this.read(buffer,offset,buffer.length); return buffer.toString(encode,0,readed).replace(/\0/g,''); } stringWithLength(offset=null,headerSize=2,encode){ var length = uints(this, offset, headerSize); return this.string(null, length, encode); } byte(offset=null){ return uints(this, offset, 1); } uint16(offset=null){ return uints(this, offset, 2); } uint24(offset=null){ return uints(this, offset, 3); } uint32(offset=null){ return uints(this, offset, 4); } uint48(offset=null){ return uints(this, offset, 6); } //轉換成可通用的 Number (數值過大將導致失真) uint64n(offset=null){ return Number(this.uint64b(offset)); } //以 BigInt 表示 uint64b(offset=null){ this.read(this.__buffer,offset); if(this.__le){ for(var i=0,j=7; i<4; i++,j--){ var s = this.__buffer[i]; this.__buffer[i] = this.__buffer[j]; this.__buffer[j] = s; } } return BigInt('0x'+this.__buffer.toString('hex')); } moveTo(offset=0){ this.pos = offset; } skip(length=1){ this.pos += length; } close(){ fs.closeSync(this.__fileSign); this.__fileSign = null; this.__buffer = null; this.__ss = null; } } |
Direct link: https://paste.plurk.com/show/wYPJdMERvWdytG2x5efv