Node.js에서 이진 데이터를 다룰 때 Buffer 객체를 사용하지만, 브라우저 환경이나 특정 API와 연동할 때는 ArrayBuffer 형태로 변환이 필요한 경우가 자주 발생합니다. 이 글에서는 Node.js Buffer를 JavaScript ArrayBuffer로 변환하는 다양한 방법을 소개합니다.
방법 1: buf.buffer 속성 직접 접근하기
가장 간단한 방법은 Buffer 인스턴스의 buf.buffer 속성에 직접 접근하는 것입니다. Buffer는 내부적으로 ArrayBuffer 위에서 동작하며, 원본 Buffer 인스턴스를 통해 데이터를 쓰면 해당 ArrayBufferView에도 그대로 반영됩니다.
다만 주의할 점이 있습니다. buf.buffer가 반환하는 ArrayBuffer는 Buffer가 실제 사용하는 영역보다 클 수 있습니다. Node.js의 Buffer는 내부 메모리 풀(pool)을 공유하기 때문에, byteOffset과 length 속성을 함께 고려해야 정확한 데이터 범위를 얻을 수 있습니다.
방법 2: 데이터 복사를 통한 변환
더 안전하고 명확한 방법은 새로운 ArrayBuffer를 생성한 후 데이터를 하나씩 복사하는 것입니다. 아래 코드 예제를 참고하세요.
function toArrayBuffer(myBuf) {
var myBuffer = new ArrayBuffer(myBuf.length);
var res = new Uint8Array(myBuffer);
for (var i = 0; i < myBuf.length; ++i) {
res[i] = myBuf[i];
}
return myBuffer;
}코드 설명
- new ArrayBuffer(myBuf.length): 원본 Buffer와 동일한 크기의 새로운 ArrayBuffer를 생성합니다.
- new Uint8Array(myBuffer): 생성된 ArrayBuffer를 바이트 단위로 조작할 수 있는 Uint8Array 뷰로 감싸줍니다.
- for 반복문: 원본 Buffer의 각 바이트를 새로운 Uint8Array에 순서대로 복사합니다.
참고 사항: Buffer와 TypedArray의 관계
Node.js 4.x 이상 버전에서는 Buffer 클래스가 Uint8Array의 하위 클래스입니다. 즉, 모든 Buffer 인스턴스는 곧 Uint8Array 인스턴스이기도 합니다. 이 덕분에 최신 Node.js 환경에서는 myBuf.buffer, slice(), TypedArray 메서드 등을 Buffer에서 직접 사용할 수 있습니다.
또한 ES6 이상 환경에서는 반복문 없이 더 간결하게 변환할 수도 있습니다.
// 간결한 현대적 방식
const arrayBuffer = myBuf.buffer.slice(
myBuf.byteOffset,
myBuf.byteOffset + myBuf.length
);이 방식은 byteOffset과 length를 활용해 Buffer가 실제로 사용 중인 메모리 구간만 정확히 잘라내므로, 내부 메모리 풀 문제를 피하면서 안전하게 변환할 수 있습니다.
정리
Node.js Buffer를 ArrayBuffer로 변환할 때는 두 가지 접근 방식을 기억하세요. 빠른 처리가 필요하면 buf.buffer 속성을 활용하되 byteOffset을 반드시 확인하고, 데이터 정합성이 중요하다면 새로운 ArrayBuffer를 만들어 복사하는 방식을 사용하는 것이 좋습니다.