-
2022-07-27 : 파일업로드 & buffer, 기타 등등TIL ( Today I Learned ) 2022. 7. 27. 10:51
1. 바이너리 데이터
바이너리 배열 : ArrayBuffer
- 자바스크립트에서 원시 바이너리(이진) 데이터를 다루는 수단으로 사용되며, 이는 메모리를 개발자가 수동으로 관리할 수 있는 대안을 제시한다.
- JS 배열과 ArrayBuffer의 차이점
ㆍ고정길이를 가지고 있고, 늘이거나 줄일 수 없다
ㆍ정확된 명시된 크기만큼의 공간을 메모리로 차지
ㆍ각각의 바이트로 접근하기 위해서는 view라고 불리는 별도의 객체 생성 후 접근
DataView
: ArrayBuffer에서 다양한 숫자 자료형의 데이터를 읽고 쓰기 위한 저수준 인터페이스를 제공
* Edian or Edianness : 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법
ㆍ바이트 순서(Byte order) : 바이드를 배열하는 방법
ㆍBig-endian : 최상위 바이트(MSB-Most Signficant Byte)부터 차례로 저장하는 방식
ㆍLittle-endian : 최하위 바이트(LSB-Least Significant Byte)부터 차례로 저장하는 방식
- 유연하게 ArrayBuffer에 접근할 수 있는 view 객체, view객체는 어떤 위치의 어떤 유형의 데이터라도 모두 접근 가능
- DataView는 개별적인 접근이 가능. 이때는 메서드를 이용해 접근하는데, 이는 .getUnit8(i) 또는 .getUnit16(i)과 같이 그 유형으로 값을 가지고 올 수 있다.
- 문법
new DataView(buffer, [byteOffset], [byteLength]);
ㆍbuffer : 기준이 되는 ArrayBuffer
ㆍbyteOffset : view 객체에서 시작할 위치
ㆍbyteLength : view 객체에 할당할 바이트 크기 ( 기본값은 buffer의 크기와 동일 )
- DataView는 동일한 ArrayBuffer에 다양한 유형이 혼합한 값을 저장하는 경우에 유용하다.
예를 들어 하나의 버퍼에 16bit와 32bit float 유형이 저장된 경우에 DataView를 이용해 손쉽게 해당 값에 접근 가능
BLOB (Binary Large Object)
- 주로 파일과 같은 객체를 바이너리 형태로 저장하는 것을 의미한다.
- 바이너리 형태로 저장하는 이유는 이미지, 오디오, 비디오와 같은 멀티미디어 파일들을 용량이 큰 경우가 많고 이를 효과적으로 데이터베이스에 저장하기 위해 고안된 자료형이라 볼 수 있다.
- 멀티미디어 파일 그 자체를 데이터베이스에 그대로 저장하기는 어렵기 때문
- 브라우저 환경에서도 JS를 이용해 BLOB 데이터에 접근 및 사용
브라우저의 File 객체 역시 BLOB의 확장형이다.
- ArrayBuffer를 통해서 바이너리 데이터를 BLOB의 형태로 변환하고, 이를 다시 원본 데이터로 변환하는 등의 작업이 가능
- BLOB은 옵션값으로 주로 MIME type을 지정할 수 있고, blobParts 라고 불리는 BLOB, ArrayBuffer, ArrayBufferView, BufferSource, DOMString 등을 인자로 받아 BLOB 객체를 생성할 수 있다
new Blob(blobParts, options)
ㆍblobParts : Blob, BufferSource, DOMString 과 같은 배열
ㆍoptions
ㆍtype : 변환될 Blob의 타입으로 주로 image/png와 같은 MIME Type
ㆍendings : 현재 OS의 newlines에 맞게 end-of-line을 지정하는 옵션(\r\n 또는 \n).
디폴트는 transparent로 아무것도 하지 않고, native 값을 넘겨주면 변환
File
- File 객체는 Blob 객체를 확장한 객체로 주로 파일시스템과 관련된 기능을 담당
new File(fileParts, fileName, [options]);
ㆍfileParts : Blob / BufferSource / String 과 같은 배열
ㆍfileName : 파일 이름 (문자열)
ㆍoptions : 옵셔널 값
ㆍlastModified : 마지막 수정이 일어난 때의 timestamp
- 예시
<input type="file" onchange="showFile(this)"> <script> function showFile(input) { let file = input.files[0]; alert(`File name: ${file.name}`); alert(`Last modified: ${file.lastModified}`); } </script>
FileReader()
: 웹 애플리케이션이 비동기적으로 데이터를 읽고 위하여 읽을 파일을 가리키는 File 혹은 Blob 객체를 이용해 파일의 내용을( 혹인 raw data버퍼로 ) 읽고 사용자의 컴퓨터에 저장하는 것을 가능하게 해준다.
읽어들인 데이터는 주로 이벤트를 사용하여 필요한 타이밍에 데이터를 전달
let reader = new FileReader();
메서드
- readAsArrayBuffer(blob) : ArrayBuffer 형태로 데이터를 읽음
- readAsText(blob, [encoding]) : encoding 방식에 맞게 텍스트 형태로 데이터를 읽음 ( 기본 인코딩 방식 utf-8 )
- readAsDataURL(blob) : base64 형태의 data url로 데이터를 읽음
- abort() : 작업을 즉시 중단
- read*로 시작하는 메서드는 우리가 어떤 포맷의 데이터를 더 선호하고, 추후에 어떤 형식으로 데이터를 다룰 것인지에 따라 다양하게 선택할 수있다
1. readAsArrayBuffer의 경우 바이너리 파일 대상으로 로우 레벨의 바이너리 작업이 필요한 경우에 유용하다. 대부분 하이레벨에서 작업하는 경우엔 File 객체가 Blob을 상속받고 있기 때문에 별도의 읽기 과정없이 즉각적으로 slice등의 메서드 호출이 가능
2. readAsText의 경우 텍스트 형태의 문자열이 필요한 경우 유용하다
3. readAsDataURL의 경우 img 태그와 같이 src 속성에 리소스를 다루어야 하는 경우 유용하다. URL.createObjectURL을 이용하는 방법도 있다.
이벤트
- loadstart : 로딩이 시작될 때
- progress : 읽기를 수행하고 있는 중
- load : 에러 없이 리딩이 완료
- abort : abort() 메서드가 호출된 때
- error : 에러가 발생한 때
- loadend : 성공/실패 여부 상관없이 리딩이 완료될 때
- 만약 읽기 가 모두 완료 시 다음 프로퍼티 접근 가능
ㆍreader.result : 성공 시 읽어들인 결과
ㆍreader.error : 실패 시 발생한 에러
<input type='file' onchange='readFile(this)' /> <script> function readFile(input) { let file = input.files[0]; let reader = new FileReader(); reader.readAsText(file); reader.onload = function() { console.log(reader.result); }; reader.onerror = function() { console.log(reader.error); }; } </script>
참고 자료 :
2. https://darrengwon.tistory.com/1256
2. Image resizing
참고 자료 : https://feel5ny.github.io/2018/05/27/JS_12/
3. react SyntheticEvent( 합성 이벤트 )
- SyntheticEvent : 객체로 모든 브라우저에서 이벤트를 동일하게 처리하기 위한 Wrapper 객체이다. 대부분의 인터페이스는 브라우저 고유 이벤트와 같다
- persist() : React v16까지 비동기 콜백함수에서 합성 이벤트 활용을 위해 사용된 메서드이다. v17부터는 풀링 최적화로 불필요해짐.
- Event Pooling(풀링)
: SyntheticEvent는 Pooling 되며 성능상의 이유로 SyntheticEvent 객체는 재사용되고 모든 속성은 이벤트 핸들러가 호출된 다음 초기화된다. 따라서, 비동기적으로 이벤트 객체에 접근할 수 없다.
react에서의 이벤트 풀링
1. SyntheticEvent Pool( 합성 이벤트 풀 )에서 SyntheticEvent 객체에 대한 참조를 받는다
2. 이벤트 정보를 SyntheticEvent 객체에 넣는다
3. 유저가 지정한 이벤트 리스너 및 핸들러가 실행된다
4. SyntheticEvent 객체가 초기화된다
function handleChange(e) { // This won't work because the event object gets reused. setTimeout(() => { console.log(e.target.value); // Too late! }, 100); }
- 즉, 이처럼 비동기적으로 SyntheticEvent 객체를 활용하게 되면, 초기화로 인해 이벤트 핸들링이 불가능하다는 개념
- 이를 방지하기 위해, e.persist() 메서드를 사용하거나, 이벤트의 값들을 변수에 담는 등의 방법을 사용
// 1) event.persist() function handleChange(e) { e.persist(); setTimeout(() => { console.log(e.target.value); }, 100); } // 2) 변수에 저장 function handleChange(e) { const { name, value } = e.target; setTimeout(() => { console.log(value); }, 100); }
- 하지만, React 17 버전부터는 이벤트 풀링 최적화를 지원하며, 이에 따라 비동기 로직에서도 합성 이벤트를 용이하게 이용
참고 자료 : https://abangpa1ace.tistory.com/129
'TIL ( Today I Learned )' 카테고리의 다른 글
2022-07-29 : JAVA & Spring (0) 2022.07.29 2022-07-28 : Spring (0) 2022.07.28 2022-07-26 : Git (0) 2022.07.26 2022-07-25 : JAVA (0) 2022.07.25 2022-07-21 : Git (0) 2022.07.21