Node.js 인터뷰 질문 16

질문: Node.js에서 파일을 읽고 쓰는 방법은 무엇인가요?

답변:

Node.js에서는 파일을 읽고 쓰기 위한 여러 가지 방법을 제공합니다. 주로 fs 모듈을 사용하며, 이 모듈은 동기식, 비동기식, 프로미스 기반, 스트림 기반 등 다양한 방식을 지원합니다.

1. 비동기식 방법 (콜백 기반)

const fs = require("fs");

// 파일 읽기
fs.readFile("input.txt", "utf8", (err, data) => {
  if (err) {
    console.error("파일 읽기 오류:", err);
    return;
  }
  console.log("파일 내용:", data);
});

// 파일 쓰기
fs.writeFile("output.txt", "안녕하세요, Node.js!", "utf8", (err) => {
  if (err) {
    console.error("파일 쓰기 오류:", err);
    return;
  }
  console.log("파일 쓰기 완료");
});

// 파일에 내용 추가
fs.appendFile("log.txt", "새로운 로그 항목\n", (err) => {
  if (err) {
    console.error("파일 추가 오류:", err);
    return;
  }
  console.log("파일 추가 완료");
});

2. 동기식 방법

const fs = require("fs");

try {
  // 파일 읽기
  const data = fs.readFileSync("input.txt", "utf8");
  console.log("파일 내용:", data);

  // 파일 쓰기
  fs.writeFileSync("output.txt", "안녕하세요, Node.js!", "utf8");
  console.log("파일 쓰기 완료");

  // 파일에 내용 추가
  fs.appendFileSync("log.txt", "새로운 로그 항목\n");
  console.log("파일 추가 완료");
} catch (err) {
  console.error("파일 작업 오류:", err);
}

3. 프로미스 기반 방법 (Node.js 10 이상)

const fs = require("fs").promises;

// 파일 읽기
fs.readFile("input.txt", "utf8")
  .then((data) => {
    console.log("파일 내용:", data);
    // 파일 쓰기
    return fs.writeFile("output.txt", "안녕하세요, Node.js!", "utf8");
  })
  .then(() => {
    console.log("파일 쓰기 완료");
    // 파일에 내용 추가
    return fs.appendFile("log.txt", "새로운 로그 항목\n");
  })
  .then(() => {
    console.log("파일 추가 완료");
  })
  .catch((err) => {
    console.error("파일 작업 오류:", err);
  });

4. async/await 사용 (Node.js 10 이상)

const fs = require("fs").promises;

async function handleFiles() {
  try {
    // 파일 읽기
    const data = await fs.readFile("input.txt", "utf8");
    console.log("파일 내용:", data);

    // 파일 쓰기
    await fs.writeFile("output.txt", "안녕하세요, Node.js!", "utf8");
    console.log("파일 쓰기 완료");

    // 파일에 내용 추가
    await fs.appendFile("log.txt", "새로운 로그 항목\n");
    console.log("파일 추가 완료");
  } catch (err) {
    console.error("파일 작업 오류:", err);
  }
}

handleFiles();

5. 스트림 방식 (대용량 파일 처리에 적합)

const fs = require("fs");

// 읽기 스트림 생성
const readStream = fs.createReadStream("large-input.txt", { encoding: "utf8" });

// 쓰기 스트림 생성
const writeStream = fs.createWriteStream("large-output.txt");

// 데이터 이벤트를 통한 처리
readStream.on("data", (chunk) => {
  console.log(`${chunk.length} 바이트 읽음`);
  // 데이터 가공/처리 가능
  writeStream.write(chunk);
});

readStream.on("end", () => {
  writeStream.end();
  console.log("읽기 완료");
});

writeStream.on("finish", () => {
  console.log("쓰기 완료");
});

// 오류 처리
readStream.on("error", (err) => console.error("읽기 오류:", err));
writeStream.on("error", (err) => console.error("쓰기 오류:", err));

// 또는 파이프를 사용해 간단하게 처리
fs.createReadStream("large-input.txt")
  .pipe(fs.createWriteStream("piped-output.txt"))
  .on("finish", () => console.log("파이프 작업 완료"));

6. 파일 디스크립터를 이용한 저수준 작업

const fs = require("fs");

// 파일 열기
fs.open("file.txt", "r+", (err, fd) => {
  if (err) {
    console.error("파일 열기 오류:", err);
    return;
  }

  // 버퍼 생성
  const buffer = Buffer.alloc(64);

  // 파일에서 읽기
  fs.read(fd, buffer, 0, buffer.length, 0, (err, bytesRead, buffer) => {
    if (err) {
      console.error("파일 읽기 오류:", err);
    } else {
      console.log(
        `${bytesRead} 바이트 읽음:`,
        buffer.slice(0, bytesRead).toString()
      );
    }

    // 파일에 쓰기
    const content = Buffer.from("새로운 내용");
    fs.write(fd, content, 0, content.length, 0, (err, bytesWritten, buffer) => {
      if (err) {
        console.error("파일 쓰기 오류:", err);
      } else {
        console.log(`${bytesWritten} 바이트 씀`);
      }

      // 파일 닫기
      fs.close(fd, (err) => {
        if (err) console.error("파일 닫기 오류:", err);
        console.log("파일 닫음");
      });
    });
  });
});

권장 사항 및 모범 사례

  1. 비동기 메서드 사용: 동기적 메서드는 메인 스레드를 차단하므로 프로덕션 환경에서는 비동기 메서드를 사용하는 것이 좋습니다.
  2. 대용량 파일에는 스트림 사용: 대용량 파일 처리 시 메모리 효율성을 위해 스트림을 사용합니다.
  3. 에러 처리 철저히: 모든 파일 작업에서 오류 처리를 반드시 포함합니다.
  4. 최신 Node.js에서는 fs.promises 활용: 비동기 코드를 깔끔하게 작성할 수 있습니다.
  5. 경로 관리에 path 모듈 사용: 크로스 플랫폼 호환성을 위해 경로 문자열 연결 대신 path.join() 사용합니다.
const path = require("path");
const filePath = path.join(__dirname, "data", "file.txt");

Node.js의 파일 시스템 모듈은 다양한 파일 작업을 처리할 수 있는 유연하고 강력한 API를 제공합니다.

results matching ""

    No results matching ""