본문 바로가기
Software/JS & TS & React

JavaScript, 파일에서 데이터(문자열, 바이너리) 불러오기

by lovey25 2023. 2. 10.
반응형

파일에서 데이터를 불러오는 방법입니다. 한번 해보면 어렵지 않은데 처음에는 비동기에 대한 개념도 부족해서 한참 헤맸던 부분이라서 정리해 봅니다.

바로 코드부터 보겠습니다.

파일에서 문자열 읽기

파일에서 문자열을 읽어오는 코드입니다. 

import { useState } from "react";

export default function App() {
  const [data, setData] = useState([]);

  const readFileData = (e) => {
    const reader = new FileReader();

    try {
      reader.onload = (result) => {
        setData(result.target.result);
      };
      reader.readAsText(e.target.files[0], "EUC-KR");
    } catch (err) {
      console.log("err", err);
    }
  };

  return (
    <>
      <input type="file" onChange={readFileData} />
      <div>{data}</div>
    </>
  );
}

<input> 태그의 ' type="file" ' 옵션을 이용해서 로컬 파일에 접근할 통로를 만들어주고 input에서 파일을 불러와 상태가 변했을 때 호출할 함수로 "readFileData"라는 이름의 함수로 연결시켜 주었습니다.

"readFileData()" 함수는 "FileReader"라는 파일처리를 편리하게 해주는 객체를 사용합니다. "FileReader"에 대한 자세한 내용은 아래 문서를 참고하시면 되겠습니다.

 

FileReader - Web APIs | MDN

The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify the file or data to read.

developer.mozilla.org

여기서는 13행에서 "readAsText()"라는 메서드를 이용해서 선택한 파일을 읽어 들이는데요. 이름에서도 알 수 있듯 문자열로 읽어줍니다. <input> 태그로 선택된 파일은 인자값으로 전달되는 이벤트로 받을 수 있는데 "event.target.files[0]"으로 받을 수 있습니다. 그리고 두 번째 인자로는 텍스트 인코딩 정보를 받으며 기본값은 "UTF-8" 되겠습니다.

"FileReader" 객체가 파일 읽기가 끝나면 "load" 이벤트가 발생하는데 "FileReader.onload" 핸들러를 통해서 파일을 읽은 후 수행할 로직을 정의할 수 있습니다.

위 예제에서는 파일이서 읽은 문자열을 useState 함수로 "data"변수에 반영해 줍니다.

결과는 다음과 같습니다. 메모장에서 ANSI 인코딩으로 저장된 텍스트는 "EUC-KR"인코딩으로 읽으니 한글도 깨지지 않고 잘 표시되네요.

 

파일에서 바이너리 데이터 읽기

이번에는 바이너리 데이터가 저장된 파일을 불러와보겠습니다. 다음과 같은 데이터가 저장된 파일이 있습니다. 이런 식의 저장방식은 데이터는 효율적으로 처리할 수 있어서 저장 용량과 성능적인 측면에서 많이 사용된다고 합니다. 

이 파일을 HEX 편집기로 열어보면 이런 데이터가 들어있는데 Uint16 형식의 데이터로 "500, 700, 800, 250"이라는 정수가 들어있습니다. (아무 의미 없는 숫자입니다.) 

이제 이 파일을 불러와 보겠습니다.

export default function App() {
  const [data, setData] = useState([]);	// 불러온 데이터를 저장할 변수

  const readFileData = (e) => {
    const reader = new FileReader();

    try {
      // 파일 읽기가 완료되면 호출되는 함수
      reader.onload = (result) => {
        let Uint16 = new Uint16Array(result.target.result);	//Uint16 형식으로 읽기
        setData(Array.from(Uint16));	// 배열로 변환해서 변수에 저장
      };
    } catch (err) {
      console.log("err", err);
    }
    reader.readAsArrayBuffer(e.target.files[0]);	// 파일 읽기
  };

  return (
    <>
      <input type="file" onChange={readFileData} />
      <div>
        {data.map((v, i) => (
          <div>
            {i}:{v}
          </div>
        ))}
      </div>
    </>
  );
}

첫 번째 예제인 문자열을 읽는 것과는 달리 파일에서 읽어온 버퍼를 Uint16Array라는 TypedArray를 이용해서 Uint16의 형식으로 파싱을 하고 파싱 된 결과를 배열로 변환해서 useState 변수에 저장합니다. 

JS에서 바이너리를 처리하는 방법에 대해서 좀 더 자세한 내용이 필요하시다면 이전 포스팅(JavaScript에서 바이너리 데이터 처리 - (ArrayBuffer, TypedArray))을 참고해 주세요.

저장된 배열은 map() 메서드를 이용해서 차례대로 컴포넌트로 전환시켜 화면에 표시하면 다음과 같은 결과를 확인할 수 있습니다.

끝!

반응형

댓글