Filesaver.js:如何编写包含二进制数据的Blob? [英] Filesaver.js: how to write a blob containing binary data?

查看:103
本文介绍了Filesaver.js:如何编写包含二进制数据的Blob?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要使用

...或者当将其读取为ArrayBuffer时,我应该得到如下结果:

  Int8Array(119)[0:01:02:03:84:605:806:797:738:789:8410:8311:6212:313:014:015:016:217:018:019:020:121:6522:023:024:025:026:027:028:3729:6430:031:032:033:034:035:036:3637:6438:039:040:041:042:043:044:3645:6446:247:048:049:050:151:6652:053:054:055:056:057:058:5259:6460:061:062:063:064:065:066:3667:6468:10269:10270:10271:10272:10273:10274:-2675:6376:277:078:079:080:181:6782:083:084:085:086:087:088:3689:6490:-5191:-5292:-5293:-5294:-5295:7696:5297:6498:099:0100:0101:0102:0103:0104:36105:64106:0107:0108:0109:9110:60111:47112:80113:79114:73115:78116:84117:83118:62] 

PS:如果您知道如何在不使用filesaver.js的情况下获得这些结果,那对我也同样适用.

我们将不胜感激!

谢谢.

解决方案

已解决:

挖掘了一段时间后,在不同的问题中发现了我需要解决的点点滴滴(不知道这是否是最佳实践,但是否可行!)

首先,我必须以不同的方式处理各种输入(字符串,数字(正整数),数字(带符号浮点实数))以匹配文件中所需的格式.

* 1:从这里得到了StingToArrayBuffer解决方案

 //字符串到ArrayBuffer函数str2ab(str){var buf = new ArrayBuffer(str.length);//每个字符2个字节var bufView = new Uint8Array(buf);对于(var i = 0,strLen = str.length; i< strLen; i ++){bufView [i] = str.charCodeAt(i);}var result = new Uint8Array(bufView.buffer);返回结果;} 

* 2:从该答案中获得了numberToArrayBuffer解决方案,已根据我的需要进行了修改!

 //.............编号为ArratBuffer//* 2//整数到ArrayBuffer-4位函数int2ArrBuf(value){const view = new DataView(new ArrayBuffer(4))for(var index = 3; index> = 0; --index){view.setUint8(索引,值%256)值=值>>8;}var int = new Uint8Array(view.buffer);返回int}//相反的顺序函数Xint2ArrBuf(value){const view = new DataView(new ArrayBuffer(4))for(var index = 0; index< = 3; ++ index){view.setUint8(索引,值%256)值=值>>8;}var int = new Uint8Array(view.buffer);返回int}//......................//一位长整数函数strsize(value){const view = new DataView(新ArrayBuffer(1))view.setUint8(0,值%256)值=值>>8;var result = new Uint8Array(view.buffer);返回结果} 

="a:=" 从这一个开始,弄清楚如何保存点坐标

 //指向ArrayBuffer-3x 8位函数Pt2ArrBuf(x,y,z){var float32 = new Float32Array(3);float32 [0] = x;float32 [1] = y;float32 [2] = z;var f = new Float64Array(float32);var pt = new Int8Array(f.buffer);返回pt;} 

* 4:准备数据序列并进行连接TypedArrays

 //在这里,我按照需要的方式编写文件...const binaryData = [int2ArrBuf(9),strsize(8),str2ab('< POINTS>'),int2ArrBuf(3),Xint2ArrBuf(2),strsize(1),str2ab('A'),Pt2ArrBuf(10.5,10,10),Xint2ArrBuf(2),strsize(1),str2ab('B'),Pt2ArrBuf(-20,10,0.7),int2ArrBuf(10),strsize(9),str2ab('</POINTS>')];//在这里,我将许多TypedArrays合并为一个...const mergedInt8Array = new Int8Array(binaryData.map(typedArray => [... new Int8Array(typedArray.buffer)]).flat());console.log(mergedInt8Array); 

* 5:大卫的Codepen

* 6:对Blob语法的更正

 //* 5:通过FileSaver.js直接下载var SaveButton = document.getElementById('save');SaveButton.addEventListener('click',function(){var filename = document.getElementById("name").value;文件名+ ='.txt';var blob = new Blob([mergedInt8Array],{type:"application/octet-stream"}});//* 6saveAs(blob,文件名);}); 

此处是 Codepen 和解决方案.谢谢.

I want to use fileSaver.js to click a button and save a binary blob (type: "application/octet-stream"). But i don´t know how to save the blob the way i need it to be.

The final file (example.mod) needs to have the following sequence:

  • 8 (the number of bytes for the next peace of information, integer number)
  • <POINTS> (a tag name with 8 characters)
  • 3 (the number of points)
  • [A,10.5,10,10] (a point: an array with a letter and 3 floating numbers)
  • [B,20,10,0.7] (a point: an array with a letter and 3 floating numbers)
  • [C,10,20.3,10] (a point: an array with a letter and 3 floating numbers)
  • 9 (the number of bytes for the next peace of information, integer number)
  • </POINTS> (a tag name with 9 characters)

I´ve found some examples saving "text/plain" or "image/png", but nothing that I could figure out how to apply in my case.

I've made this CodePen showing what I´m trying to do, but the resulting file is not what expected! it returns a file like that (all the information is visible as if was a text file):

8<POINTS>3A,10.5,10,10B,20,10,0.7C,10,20.3,109</POINTS>

...but what I would like to get is the file writen in Bytes, something like this (when looked at in a text-editor):

...or when read it as an ArrayBuffer I should get something like this result:

Int8Array(119)[
    0: 0
    1: 0
    2: 0
    3: 8
    4: 60
    5: 80
    6: 79
    7: 73
    8: 78
    9: 84
    10: 83
    11: 62
    12: 3
    13: 0
    14: 0
    15: 0
    16: 2
    17: 0
    18: 0
    19: 0
    20: 1
    21: 65
    22: 0
    23: 0
    24: 0
    25: 0
    26: 0
    27: 0
    28: 37
    29: 64
    30: 0
    31: 0
    32: 0
    33: 0
    34: 0
    35: 0
    36: 36
    37: 64
    38: 0
    39: 0
    40: 0
    41: 0
    42: 0
    43: 0
    44: 36
    45: 64
    46: 2
    47: 0
    48: 0
    49: 0
    50: 1
    51: 66
    52: 0
    53: 0
    54: 0
    55: 0
    56: 0
    57: 0
    ​​58: 52
    ​​59: 64
    ​​60: 0
    ​​61: 0
    ​​62: 0
    ​​63: 0
    ​​64: 0
    65: 0
    66: 36
    ​​67: 64
    ​​68: 102
    ​​69: 102
    ​​70: 102
    ​​71: 102
    72: 102
    ​​73: 102
    ​​74: -26
    ​​75: 63
    76: 2
    77: 0
    ​​78: 0
    79: 0
    ​​80: 1
    ​​81: 67
    ​​82: 0
    ​​83: 0
    ​​84: 0
    ​​85: 0
    ​​86: 0
    87: 0
    ​​88: 36
    ​​89: 64
    ​​90: -51
    ​​91: -52
    ​​92: -52
    ​​93: -52
    ​​94: -52
    ​​95: 76
    96: 52
    ​​97: 64
    98: 0
    ​​99: 0
    100: 0
    ​​101: 0
    ​​102: 0
    ​​103: 0
    ​​104: 36
    105: 64
    ​​106: 0
    107: 0
    108: 0
    ​​109: 9
    ​​110: 60
    ​​111: 47
    ​​112: 80
    ​​113: 79
    ​​114: 73
    ​​115: 78
    ​​116: 84
    ​​117: 83
    ​​118: 62
]

PS: If you know how to get those results without using filesaver.js, that would work for me as well.

Any help will be most appreciated!

Thank you.

解决方案

Solved:

After digging for a while found in different questions the bits and peaces i needed to put together a solution (not sure if is the best practice, but is working!)

First I had to treat every kind of input (string, number(positive integer), number(signed floating real) in differnet ways to match the format I need in the file.

*1: from here got the StingToArrayBuffer solution

//string to ArrayBuffer
function str2ab(str) {
  var buf = new ArrayBuffer(str.length); // 2 bytes for each char
  var bufView = new Uint8Array(buf);
  for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  var result = new Uint8Array(bufView.buffer);
  return result;
}

*2: From that answer got the numberToArrayBuffer solution, modified to my needs!

//.............number to ArratBuffer //*2
//integer To ArrayBuffer - 4 bits
function int2ArrBuf(value) {
  const view = new DataView(new ArrayBuffer(4))
  for (var index = 3; index >= 0; --index) {
    view.setUint8(index, value % 256)
    value = value >> 8;
  }
  var int = new Uint8Array(view.buffer);
  return int
}

//Reverse order
function Xint2ArrBuf(value) {
  const view = new DataView(new ArrayBuffer(4))
  for (var index = 0; index <= 3; ++index) {
    view.setUint8(index, value % 256)
    value = value >> 8;
  }
  var int = new Uint8Array(view.buffer);
  return int
}
//......................

//one bit long integer
function strsize(value) {
  const view = new DataView(new ArrayBuffer(1))
  
    view.setUint8(0, value % 256)
    value = value >> 8;
 
  var result= new Uint8Array(view.buffer);
  return result
}

*3: from this one, figure how to save the point coordinates

//point To ArrayBuffer - 3x 8 bits
function Pt2ArrBuf(x,y,z){
  var float32 = new Float32Array(3);
  float32[0] = x;
  float32[1] = y;
  float32[2] = z;

  var f = new Float64Array(float32);
  var pt = new Int8Array(f.buffer);  
  
  return pt;
}

*4: preparing the data sequence and concatenating the TypedArrays

//here I write the file the way i Need it to be...

const binaryData = [
    int2ArrBuf(9),
    strsize(8),
    str2ab('<POINTS>'),
    int2ArrBuf(3),
    Xint2ArrBuf(2),
    strsize(1),
    str2ab('A'),
    Pt2ArrBuf(10.5,10,10),
    Xint2ArrBuf(2),
    strsize(1),
    str2ab('B'),
    Pt2ArrBuf(-20,10,0.7),
    int2ArrBuf(10),
    strsize(9),
    str2ab('</POINTS>') 
  ];

//here I join the many TypedArrays into one...
const mergedInt8Array = new Int8Array(binaryData.map(typedArray => [...new Int8Array(typedArray.buffer)]).flat());
console.log(mergedInt8Array);

*5: Codepen from David

*6: Correction on the blob syntax

//*5:direct download via FileSaver.js
var SaveButton = document.getElementById('save');
SaveButton.addEventListener('click', function () {
  var filename = document.getElementById("name").value;
  filename += '.txt';
  var blob = new Blob([mergedInt8Array], { type: "application/octet-stream"}); //*6
  saveAs(blob, filename);
});

Here is the Codepen with the Solution. Thank You.

这篇关于Filesaver.js:如何编写包含二进制数据的Blob?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆