Program Tip

node.js의 버퍼에 바이너리 데이터를 추가하는 방법

programtip 2020. 11. 20. 09:28
반응형

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

반응형