【发布时间】:2019-02-28 12:07:13
【问题描述】:
我创建了一个缓冲区,然后在其上创建了一个 Uint8Array,但该数组没有任何值。我希望它具有缓冲区的值。这是一个易于重现的示例:
var buf = new ArrayBuffer(32);
for (var index = 0; index < 32; index++) buf[index] = index;
console.log(buf);
var arr = new Uint8Array(buf);
console.log(arr);
我在现实中尝试的是这样的日期格式转换器:
//Buffers and views
function convertDateTimeToFormat(date, initialFormat, endFormat) {
var buf = new ArrayBuffer(14);
var result = new Uint8Array(buf);
console.log(date);
var initialPositions = {};
var endPositions = {};
var sizeSoFar = 0;
for (var c of initialFormat) {
if (c === 'y') {
initialPositions.y = new Uint32Array(date, sizeSoFar, 1);
} else {
initialPositions[c] = new Uint8Array(date, sizeSoFar, 2);
}
sizeSoFar += ((c === 'y') ? 4 : 2);
}
sizeSoFar = 0;
for (var c of endFormat) {
if (c === 'y') {
endPositions.y = new Uint32Array(buf, sizeSoFar, 1);
} else {
endPositions[c] = new Uint8Array(buf, sizeSoFar, 2);
}
sizeSoFar += ((c === 'y') ? 4 : 2);
}
for (var key in initialPositions) {
var limit = (key === 'y') ? 4 : 2;
for (var index = 0; index < limit; index++) endPositions[c][index] = initialPositions[c][index];
}
return result;
}
//2019-03-01 13:03:50
var buf = new ArrayBuffer( 14 );
buf[0] = 2;
buf[1] = 0;
buf[2] = 1;
buf[3] = 9;
buf[4] = 0;
buf[5] = 3;
buf[6] = 0;
buf[7] = 1;
buf[8] = 1;
buf[9] = 3;
buf[10] = 0;
buf[11] = 3
buf[12] = 5;
buf[13] = 0;
console.log(convertDateTimeToFormat(buf, "yMdHms", "yMdHms"));
console.log(convertDateTimeToFormat(buf, "yMdHms", "MdyHms"));
但是由于我在这个问题开始时描述的行为,结果都是零。
这可行,但并不优雅,因为它需要日期格式,如果我要确保输入与日期格式无关,那么代码将变得非常复杂:
//Buffers and views
var results = {};
var buf = new ArrayBuffer( 4 );
results.uint32 = new Uint32Array(buf);
results.int8 = new Uint8Array(buf);
results.uint8 = new Int8Array(buf);
results.int8[2] = -1;
console.log(results);
results.int8[2] = 0;
results.int8[1] = -1;
console.log(results);
results.int8[1] = 0;
results.int8[0] = -1;
console.log(results);
//Buffers and views
function convertDateTimeToFormat(date, format) {
var buf = new ArrayBuffer(14);
var result = new Uint8Array(buf);
var positions = {
y: 0,
M: 4,
d: 6,
H: 8,
m: 10,
s: 12
};
for (var index = 0; index < 14; index++) {
result[index] = date[positions[format[index]]++];
}
return result.join("");
}
var results = {};
//2019-03-01 13:03:50
var buf = new ArrayBuffer( 14 );
buf[0] = 2;
buf[1] = 0;
buf[2] = 1;
buf[3] = 9;
buf[4] = 0;
buf[5] = 3;
buf[6] = 0;
buf[7] = 1;
buf[8] = 1;
buf[9] = 3;
buf[10] = 0;
buf[11] = 3
buf[12] = 5;
buf[13] = 0;
console.log(convertDateTimeToFormat(buf, "yyyyMMddHHmmss"));
console.log(convertDateTimeToFormat(buf, "MMddyyyyHHmmss"));
【问题讨论】:
-
为什么还要使用缓冲区而不是简单的纯字符串?
-
在您的第一个示例中,当您
console.log(arr.buffer);时,您会注意到Uint8Array实际上确实记录了ArrayBuffer。 -
我认为这就像 Bergi 所说的那样,它只是一片内存,而 Uint8Array 只是无法直接访问其内容。我想知道为什么在 mdn 文档中,如果没有复制值,他们允许使用 ArrayBuffer 构造 Uint8Array 。没有多大意义。
-
@kemicofa 这正是我的问题。我知道我可以解决问题,例如从缓冲区读取每个字节并填充我的视图,但我还必须注意字节顺序,这在我看来完全违背了拥有类型化数组的目的.因此,如果有一种解决方案可以从缓冲区中自动填充 Uint 视图,那么如果想要进行微优化,那么使用类型化数组将是有意义的。如果不是,那我根本不明白为什么我们有类型数组。
-
@kemicofa 的“自动”我当然是指语言级别,而不是为其编写算法。
标签: javascript