Filesaver.js:如何编写包含二进制数据的Blob? [英] Filesaver.js: how to write a blob containing binary data?
问题描述
我要使用
...或者当将其读取为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屋!