node.js의 버퍼에 바이너리 데이터를 추가하는 방법
바이너리 데이터가있는 버퍼가 있습니다.
var b = new Buffer ([0x00, 0x01, 0x02]);
그리고 나는 추가하고 싶다 0x03
.
이진 데이터를 더 추가하려면 어떻게해야합니까? 문서에서 검색 중이지만 데이터를 추가하려면 문자열이어야합니다. 그렇지 않으면 오류가 발생합니다 ( TypeError : Argument must be a string ).
var b = new Buffer (256);
b.write ("hola");
console.log (b.toString ("utf8", 0, 4)); //hola
b.write (", adios", 4);
console.log (b.toString ("utf8", 0, 11)); //hola, adios
그런 다음 여기서 볼 수있는 유일한 해결책은 추가 된 모든 이진 데이터에 대해 새 버퍼를 만들고 올바른 오프셋을 사용하여 주 버퍼에 복사하는 것입니다.
var b = new Buffer (4); //4 for having a nice printed buffer, but the size will be 16KB
new Buffer ([0x00, 0x01, 0x02]).copy (b);
console.log (b); //<Buffer 00 01 02 00>
new Buffer ([0x03]).copy (b, 3);
console.log (b); //<Buffer 00 01 02 03>
그러나 매번 추가 할 때마다 새 버퍼를 인스턴스화해야하기 때문에 이것은 약간 비효율적으로 보입니다.
바이너리 데이터를 추가하는 더 좋은 방법을 알고 있습니까?
편집하다
내가 작성한 BufferedWriter의 내부 버퍼를 사용하여 파일에 바이트를 기록합니다. BufferedReader 와 동일 하지만 쓰기 용입니다.
간단한 예 :
//The BufferedWriter truncates the file because append == false
new BufferedWriter ("file")
.on ("error", function (error){
console.log (error);
})
//From the beginning of the file:
.write ([0x00, 0x01, 0x02], 0, 3) //Writes 0x00, 0x01, 0x02
.write (new Buffer ([0x03, 0x04]), 1, 1) //Writes 0x04
.write (0x05) //Writes 0x05
.close (); //Closes the writer. A flush is implicitly done.
//The BufferedWriter appends content to the end of the file because append == true
new BufferedWriter ("file", true)
.on ("error", function (error){
console.log (error);
})
//From the end of the file:
.write (0xFF) //Writes 0xFF
.close (); //Closes the writer. A flush is implicitly done.
//The file contains: 0x00, 0x01, 0x02, 0x04, 0x05, 0xFF
마지막 업데이트
concat을 사용하십시오 .
Node.js ~> 0.8에 대한 업데이트 된 답변
var newBuffer = Buffer.concat([buffer1, buffer2]);
Node.js ~ 0.6에 대한 이전 답변
모듈을 사용하여 .concat
기능 을 추가합니다 .
https://github.com/coolaj86/node-bufferjs
"순수한"솔루션이 아니라는 것을 알고 있지만 제 목적에 매우 적합합니다.
버퍼는 항상 고정 된 크기이며 동적으로 크기를 조정할 수있는 방법이 없으므로 더 큰 버퍼에 복사하는 방법이 유일한 방법입니다.
그러나보다 효율적으로 버퍼를 원래 내용보다 크게 만들 수 있으므로 버퍼를 재할 당하지 않고 데이터를 추가 할 수있는 "여유"공간이 있습니다. 이렇게하면 새 버퍼를 만들고 각 추가 작업에서 내용을 복사 할 필요가 없습니다.
이것은 순수한 접근 방식을 원하는 솔루션을 찾는 모든 사람들을 돕기위한 것입니다. 이 문제는 JS Buffer 객체뿐만 아니라 여러 곳에서 발생할 수 있기 때문에이 문제를 이해하는 것이 좋습니다. 문제가 존재하는 이유와 해결 방법을 이해하면이 문제가 매우 근본적이기 때문에 향후 다른 문제를 해결하는 능력을 향상시킬 수 있습니다.
다른 언어로 이러한 문제를 처리해야하는 우리에게는 해결책을 고안하는 것이 매우 당연하지만 복잡성을 추상화하고 일반적으로 효율적인 동적 버퍼를 구현하는 방법을 깨닫지 못하는 사람들이 있습니다. 아래 코드는 더 최적화 될 가능성이 있습니다.
예제의 크기를 작게 유지하기 위해 read 메서드를 구현하지 않은 채로 두었습니다.
The realloc
function in C (or any language dealing with intrinsic allocations) does not guarantee that the allocation will be expanded in size with out moving the existing data - although sometimes it is possible. Therefore most applications when needing to store a unknown amount of data will use a method like below and not constantly reallocate, unless the reallocation is very infrequent. This is essentially how most file systems handle writing data to a file. The file system simply allocates another node and keeps all the nodes linked together, and when you read from it the complexity is abstracted away so that the file/buffer appears to be a single contiguous buffer.
단순히 고성능 동적 버퍼를 제공하는 것의 어려움을 이해하고자하는 분들은 아래 코드 만보고 메모리 힙 알고리즘과 프로그램에서 메모리 힙이 작동하는 방식에 대한 연구를 수행하면됩니다.
대부분의 언어는 성능상의 이유로 고정 크기 버퍼를 제공 한 다음 크기가 동적 인 다른 버전을 제공합니다. 일부 언어 시스템은 핵심 기능을 최소화 (코어 배포)하고 개발자가 추가 또는 더 높은 수준의 문제를 해결하기 위해 라이브러리를 만들도록 권장하는 타사 시스템을 선택합니다. 이것이 왜 언어가 일부 기능을 제공하지 않는지 의문을 제기하는 이유입니다. 이 작은 핵심 기능을 사용하면 언어를 유지 관리하고 향상시키는 데 드는 비용을 줄일 수 있지만 결국에는 자체 구현을 작성하거나 타사에 의존해야합니다.
var Buffer_A1 = function (chunk_size) {
this.buffer_list = [];
this.total_size = 0;
this.cur_size = 0;
this.cur_buffer = [];
this.chunk_size = chunk_size || 4096;
this.buffer_list.push(new Buffer(this.chunk_size));
};
Buffer_A1.prototype.writeByteArrayLimited = function (data, offset, length) {
var can_write = length > (this.chunk_size - this.cur_size) ? (this.chunk_size - this.cur_size) : length;
var lastbuf = this.buffer_list.length - 1;
for (var x = 0; x < can_write; ++x) {
this.buffer_list[lastbuf][this.cur_size + x] = data[x + offset];
}
this.cur_size += can_write;
this.total_size += can_write;
if (this.cur_size == this.chunk_size) {
this.buffer_list.push(new Buffer(this.chunk_size));
this.cur_size = 0;
}
return can_write;
};
/*
The `data` parameter can be anything that is array like. It just must
support indexing and a length and produce an acceptable value to be
used with Buffer.
*/
Buffer_A1.prototype.writeByteArray = function (data, offset, length) {
offset = offset == undefined ? 0 : offset;
length = length == undefined ? data.length : length;
var rem = length;
while (rem > 0) {
rem -= this.writeByteArrayLimited(data, length - rem, rem);
}
};
Buffer_A1.prototype.readByteArray = function (data, offset, length) {
/*
If you really wanted to implement some read functionality
then you would have to deal with unaligned reads which could
span two buffers.
*/
};
Buffer_A1.prototype.getSingleBuffer = function () {
var obuf = new Buffer(this.total_size);
var cur_off = 0;
var x;
for (x = 0; x < this.buffer_list.length - 1; ++x) {
this.buffer_list[x].copy(obuf, cur_off);
cur_off += this.buffer_list[x].length;
}
this.buffer_list[x].copy(obuf, cur_off, 0, this.cur_size);
return obuf;
};
참고URL : https://stackoverflow.com/questions/10355856/how-to-append-binary-data-to-a-buffer-in-node-js
'Program Tip' 카테고리의 다른 글
Wix에서 이전에 설치된 프로그램 버전을 업데이트하는 방법 (0) | 2020.11.20 |
---|---|
postgreSQL에서 테이블 생성 (0) | 2020.11.20 |
"mscorlib.pdb가로드되지 않음"아직 mscorlib.dll이 누락되지 않았습니다. (0) | 2020.11.20 |
R을 충돌시키는 방법? (0) | 2020.11.20 |
새 Google Recaptcha (v2) 너비 변경 (0) | 2020.11.20 |