파일 형식(Base64, Blob, ArrayBuffer, File) 개념 및 장단점 정리

장택진·2024년 8월 7일
0

회사에서 B2C 웹 프로젝트를 진행하면서 멀티미디어 파일을 다룰 일이 많았는데, 당시엔 그저 하란대로만 했다.
개발을 하면서도 왜 여기선 buffer를 쓰지? 왜 여긴 base64로 달라고 하지? 같은 자잘한 궁금증을 품고 있었어서 파일 형식에 대한 개념과 장단점을 정리해보려고 한다.

이진데이터(binary)

브라우저에서 멀티미디어 파일을 텍스트생성, 업로드, 다운로드를 하거나 이미지 파일을 다뤄야한다면 이진데이터를 다뤄야 한다.

컴퓨터는 우리가 사용하는 모든 데이터를 0과 1로 저장한다.
이진데이터는 0과 1만을 사용하여 2개의 수를 나타내는 진법을 뜻하고, 컴퓨터를 다루는데 있어 가장 근본이 되는 체계라고 볼 수 있다.

Base64

Base64는 이진 데이터를 텍스트 형식으로 변환하는 인코딩 방식이다. html에 img의 src에 삽입된 이미지 url이 아닌 숫자와 문자로 구성된 긴 코드(data:image/png;base64)가 base64이다.

우리가 소스 코드 단에 이미지를 불러와 다루어야 할때 링크를 통해 불러오거나 로컬 폴더에 저장되어 있는 이미지 파일을 코드에서 제공하는 파일 시스템을 통해 상대경로로 불러와 다뤄본 경험이 있을 것이다. 하지만 파일도 결국 url과 같이 OS에 저장된 징검다리(연결선)를 불러온 것과 같다.

그러나 base64로 변환해주면 우리가 직접 소스 코드 단에 이미지 데이터 자체를 저장할 수 있게 된다. 우리가 변수에 문자열이나 숫자를 저장하는 것처럼 변수에 이미지를 저장할 수 있는 것이다.

base64는 이미지 데이터 값을 변환하는 것이 아닌 그냥 출력 형식을 변환하는 것이기 때문에 이미지 자체가 바뀌는 것이 아니다. 즉, 이미지 데이터 정보는 이미 base64 텍스트 자체에 포함되어 있기 때문에 결과적으로 링크 url을 통해 서버에 요청하지 않고도 직접 이미지를 사용할 수 있게 된다.

이렇게 base64로 변환하면 직접 바이너리를 다룬다는 특징도 있지만, 바이너리 데이터를 텍스트로 바꾸는 64진법 인코딩을 통해, 바이너리 데이터 대비 33%의 데이터의 양 증가하게 된다는 단점이 있다. 하지만 데이터의 길이가 증가함에도, Base64를 사용하는 가장 큰 이유는 앞서 소개하듯이 Binary 데이터를 텍스트 기반 규격으로 다룰 수 있기 때문이다.

또한 순수 바이너리 형식으로 남아있는보다 전송/저장이 훨씬 쉽다는 점도 꼽을 수 있다. (이진 데이터는 0과 1로 이루어져있고 제어 문자나 특수 문자가 포함될 수 있어서 손상될 확률이 높다)

  • 장점

    • 별도 이미지 파일이 필요없다. 왜냐하면 base64 데이터 자체가 이미지이기 때문.
    • 브라우저 렌더링시, 문서로딩과 같이 로딩 되기에 끊기지 않고 불러온다. 또한 네트워크가 좋지않아도 위와 같은 특징으로 이미지를 로딩할수 있다는 점도 있다.
  • 단점

    • 문자열이 매우매우 길기에 가독성이 떨어진다.
    • Base64 인코딩을 사용하면 원본보다 33%의 용량이 커져서, 남용할경우 오히려 로딩 속도가 저하될 수 있다.

Blob (Binary Large Object)

BLOB은 Binary Large OBject의 약자로 주로 이미지, 오디오, 비디오와 같은 멀티미디어 파일 바이너리를 객체 형태로 저장한 것을 의미한다. 멀티미디어 파일들은 대다수 용량이 큰 경우가 많기 때문에, 이를 데이터베이스에 효과적으로 저장하기 위해 고안된 자료형이라 볼 수 있다. (string 타입, number 타입이 있듯이 blob 타입이 있다고 이해하면 된다.)

예를들어 데이터베이스에 이미지 파일을 그대로 데이터로 저장하고 싶을때, 바로 blob 포맷으로 변환한 뒤 저장하는 것이다. 브라우저 환경에서도 자바스크립트를 이용해 이러한 blob 데이터에 접근하고 사용할 수 있다.

주로 자바스크립트에서 텍스트, 이미지, 사운드, 비디오와 같은 멀티미디어 데이터를 다룰 때 사용한다.

ex)

Blob 객체에는 별도로 type(image/png) 을 명시하기 때문에 Blob 객체를 다운로드/업로드 하는 과정에서 네트워크 요청에서의 Content-Type은 자연스레 명시된 type으로 매칭된다.

base64와 어떤점이 다른지 비교해보자.

  • base64는 바이너리 데이터를 다루기 위해 텍스트(문자열) 형태로 저장한 포맷이라고 했었다.
  • blob이란 바이너리 데이터를 다루기 위해 객체(Object) 저장하는 것이다.

blob 데이터는 적절하게 object url로 변환만 해주면 심플하게 브라우저에서 사용할수 있다. 그리고 blob은 객체이기 때문에 다양한 코드 활용성을 지니고 있어, base64로 변환할수도 있고 뒤에서 배울 buffer로도 변환할수도 있다.

이때 변환된 URL은 현재 탭의 브라우저 메모리에 저장되고, 저장된 URL은 매핑된 Blob 객체를 참고하고 있는 형태이다. 이러한 원리 때문에, base64와는 달리 짧은 문자열만으로도 원래의 Blob 객체에 접근이 가능하고 그에 따른 이미지 등의 파일을 가져올 수 있는 것이다. 그래서 변환된 URL은 항상 현재 문서에서만 유효하다. (현재 브라우저 메모리에 적재된 상태니까)

변환된 URL을 현재 문서를 새로고침하거나 아니면 다른 페이지에서 사용하려고 한다면 제대로 사용할 수 없다.

Blob 객체가 URL로 변환되어 매핑이 이루어진 채 메모리에 저장되게 되면, 명시적으로 해당 URL이 해제되기 전까지 브라우저는 해당 URL이 유효하다고 판단하기 때문에 자바스크립트 엔진에서 가비지 컬렉션이 이루어지지 않는다.

따라서 blob URL을 사용한 이후, 더 이상 사용하지 않을 시점이라고 판단되면 명시적으로 해제해 주는 것이 좋다.

변환은 URL.createObjectURL 메서드를 통해 진행하고, 해제의 경우에는 URL.revokeObjectURL 메서드를 사용한다.

이는 내부적으로 매핑되어 있는 참조를 지우는 메서드로, 메모리에 상주하고 있는 Blob 객체를 지울 수 있다.

예를 들어 이미지를 화면에 출력이 아닌 오로지 이미지 다운으로 blob을 사용한다고 하면, 동적으로 생성한 Blob 객체는 오직 다운로드 클릭 순간에만 필요하고 그 이후엔 필요하지 않기 때문에 해제를 통해 메모리 누수를 방지할 수 있다.

ArrayBuffer

ArrayBuffer 객체는 이미지, 동영상과 같은 멀티미디어 데이터 덩어리를 표준 자바스크립트(브라우저)에서 다루기 위해 도입됐다.

일반적으로 실시간 방송과 같이 영상 내용을 송출할 때에는 영상이라고 하는 실시간 데이터를 계속해서 전달해줘야 유저들이 볼 수 있다. 즉, 어떤 식으로든 커다란 데이터를 잘개 쪼개서 전송해야 하는 상황이 발생한다.

여기서 버퍼(buffer)라는 개념이 등장하는데, 일정 구획만큼의 데이터를 쪼개서 전달하는 stream을 저장한 후 일정 크기가 도달하면 출력 장치나 동영상 플레이어로 전달해주는 중개자 역할을 하는 객체라고 보면 된다. (버퍼링이 걸리는 이유)

따라서 자바스크립트 용도가 다양해지면서 이처럼 오디오나 비디오 같은 이진 데이터들 역시 다룰 필요성이 생기게 되자, 필요한 메모리 공간을 적절하게 할당해서 사용할 수 있는 유연성이 필요해 ArrayBuffer를 만들게 되었다고 이해하면 된다.

ArrayBuffer는 자바스크립트에서 원시 데이터를 직접 다루는 수단으로 사용되며, 이는 메모리를 개발자가 수동으로 관리할 수 있게 해준다.

지금까지 배운 base64와 blob은 사람이 읽고 다루기 편하게 가공된 데이터 타입이라면, ArrayBuffer는 보다 오리지널에 가깝다고 보면 된다. 레퍼런스 타입으로 되어 있으며, 고정된 길이의 연속된 메모리 공간을 할당해 사용하겠다고 알려주는 역할을 한다.
(오디오 전용인 AudioBuffer, 미디어 전용인 SourceBuffer도 있다.)

특히 성능에 민감한 이슈를 다룬다거나 blob 등의 큰 용량의 파일 데이터를 다루는 경우 ArrayBuffer를 사용해 유연하고 효율적으로 작업할 수 있다.

이름에 array가 있다고 하여 ArrayBuffer가 자바스크립트 배열과 같진 않다.
ArrayBuffer는 그저 메모리의 연속된 공간을 차지하고 있는 추상적인 메모리 계층과도 같다.
ArrayBuffer는 자바스크립트의 배열과 비교해 다음과 같은 차이점이 있다.

  • 고정길이를 가지고 있고, 이를 늘이거나 줄일 수 없다.
  • 정확히 명시된 크기만큼의 공간을 메모리에서 차지한다.
  • 각각의 바이트에 접근하기 위해서는, 일반 배열처럼 buffer[index]와 같이 인덱스를 통해 접근할 수 없다. 대신에 view라고 불리는 별도의 객체를 생성해서 접근해야 한다.

Buffer

데이터 덩어리를 다루기 위해 Node.js는 진작부터 Buffer 타입을 도입했다

버퍼는 고정된 크기의 데이터 덩어리를 표현하기 위한 타입이며, Node.js 의 많은 API들이 Buffer 타입을 지원한다.

fs 모듈로 로컬 파일을 가져오는 것도 사실 버퍼로 가져오는 것이다.

클라이언트단에서 ArrayBuffer로 이진 데이터를 다루었다면, 서버단(Node.js)에서는 Buffer 객체로 이진 데이터를 다룬다고 이해하면 된다.

Node.js에서 멀티미디어 파일을 다룬다고 하면 무조건 Buffer를 이용해 다룬다고 이해하면 된다.

File, FileReader

File

파일은 우리에게 매우 익숙한 타입이지만, 자바스크립트에서의 File 객체는 Blob 객체를 확장한 객체로 주로 파일시스템과 관련된 기능을 담당한다.

파일시스템은 OS/서버단의 영역인데, 브라우저 상에서도 파일을 주고 받는 등의 기능이 필요하기 때문에 이를 지원하기 위한 규격으로 볼 수 있다.

브라우저에서 자바스크립트를 이용해 파일을 다루기 위한 방법으로는 File 객체를 이용하거나 html의 input태그를 이용하는 두 가지가 있다.

FileReader

FileReader는 Blob 또는 File과 같은 객체로부터 데이터를 읽어 들이기위한 목적으로 사용되는 객체이다.

읽어들인 데이터는 주로 이벤트를 사용하여 필요한 타이밍에 데이터를 전달한다.

출처 : Inpa Dev, Base64-Blob-ArrayBuffer-File-다루기-정말-이해하기-쉽게-설명

profile
필요한 것은 노력과 선택과 치킨

0개의 댓글