etc

CRLF와 LF

하리하링웹 2024. 8. 8. 22:30

최근 개발도중 파일 비교 작업을 하고있는데 아무리 봐도 같은 파일인데 자바스크립트상에서 비교시 파일이 다르다는 문제가 발생하였다.

 

기존에는 아래와 같은 코드로 content를 얻어 사용하고 있었는데 디버깅을 위해 utf8 방식의 디코딩을 사용하지 않고 버퍼 상태 그대로 받아 차이점을 비교해보았다.

const content1 = fs.readFileSync(file1.fullPath, 'utf8');
const content2 = fs.readFileSync(file2.fullPath, 'utf8');

 

[결과]

  const content1 = fs.readFileSync(file1Path);
  const content2 = fs.readFileSync(file2Path);

  console.log('file1', content1);
  console.log('file2', content2);

  console.log('compare', content1 === content2);
  
  //file1 <Buffer 65 78 70 6f 72 74 20 2a 20 66 72 6f 6d 20 27 2e 2f 44 61 74 61 4d 6f 64 65 6c 43 6f 6d 6d 6f 6e 27 3b 0d 0a 65 78 70 6f 72 74 20 2a 20 66 72 6f 6d 20 ... 283 more bytes>
  //file2 <Buffer 65 78 70 6f 72 74 20 2a 20 66 72 6f 6d 20 27 2e 2f 44 61 74 61 4d 6f 64 65 6c 43 6f 6d 6d 6f 6e 27 3b 0a 65 78 70 6f 72 74 20 2a 20 66 72 6f 6d 20 27 ... 275 more bytes>
  //compare false

 

두 개의 파일은 내용이 같은 파일이다. 하지만 결과는 다르게 나온다. 버퍼를 비교해보면 이상한 부분이 있다.

 

일단 첫 번째로 한 쪽의 파일에는 0d라는 한 바이트의 값이 추가되어있다.

 

두 번째는 한 쪽의 파일이 8바이트 (앞쪽까지 포함하면 9바이트) 가 더 크다는 것이다.

 

여기서 0d 라는 값이 아스키 코드로 어떤 값인지를 먼저 알아봤다.

 

0d 는 캐리지 리턴이라는 값인데 이 정의는 아래와 같다.

캐리지 리턴(carriage return), 카트리지 리턴(영어: cartridge return) 또는 간단히 리턴(return)은 문자의 새 줄을 시작하는 데 쓰이는 제어 문자나 그 구조를 가리킨다. 컴퓨터 환경에서는 간단히 CR로 줄여 쓴다.

 

즉 해당 값이 코드 각 줄의 마지막 부분에 들어갔으며 파일은 총 9줄의 코드를 가진 파일이였기에 9개의 CR 값이 추가되어

9바이트가 차이가 나게 되는것이였다.

 

실제로 vscode에서 파일 양식을 확인해 보면 한 쪽은 CRLF, 다른 한 쪽은 LF 형태로 되어있는것을 확인할 수 있다.

 

해결 방법은 간단했다. 파일 비교시에 normalize 과정을 거치게 만들면 된다.

 

파일 비교 전 아래 코드를 추가한 뒤 파일 콘텐츠를 비교해보자

// 캐리지 리턴(CR) 문자를 제거하고 비교
const normalizedContent1 = content1.replace(/\r/g, '');
const normalizedContent2 = content2.replace(/\r/g, '');

이후 정상적으로 테스트가 동작하는 것을 확인할 수 있었다.

 

그렇다면 왜 이런 차이가 생기는걸까?

 

이유는 운영체제별로 채택한 줄바꿈 방식이 다르기 떄문이다. 현재 Window 운영체제의 경우 CRLF를 채택하여 사용하고 있고 UNIX 계열의 경우 LF를 채택하여 사용하고 있다.

 

따라서 맥OS와 같은 곳에서 작업한 파일을 받아 윈도우에서 생성한 파일과 비교하려하면 파일의 줄바꿈 양식이 달라 비교 연산에서 false를 반환하게 되는 것이다.

 

또한 vscode에서 파일을 열 때 해당 파일의 줄바꿈을 확인하여 이를 파일의 기본 줄바꿈으로 적용하기에 CRLF 양식으로 이루어진 파일의 코드를 복사하여 LF 양식의 파일에 붙여넣더라도 vscode는 붙여넣어지는 파일의 기본 줄바꿈이 LF 양식이기에 자동으로 LF 양식으로 변경되어 저장되게된다.

 

따라서 프로젝트단에서 이러한 문제를 해결하려면 eslint 설정을 통해 프로젝트의 줄바꿈 양식을 통일하거나 git의 autocrlf 옵션을 사용하여 줄바꿈을 통일해주는 등의 방법이 있다.