POSIX 기반 프로그램을 사용해 VOS 구조화 파일을 처리해 본 적이 있다면, 몇 가지 제한 사항을 경험하거나 이해하기 어려운 동작을 목격했을 수 있습니다. 이 글에서는 그 원인을 설명해 보겠습니다.
VOS는 4가지 유형의 파일을 지원합니다: 순차, 상대, 고정, 스트림. 처음 3가지 형식은 파일 시스템이 레코드 경계를 추적하기 때문에 "구조화" 파일이라고 합니다. 사용 가능한 I/O 작업은 전체 레코드를 읽고 씁니다. 마지막 형식은 레코드 경계가 암시적이며, 줄바꿈 문자가 레코드를 구분하기 때문에 "비구조화"라고 합니다. 사용 가능한 I/O 작업은 바이트 시퀀스를 읽고 씁니다.
유닉스® 또는 리눅스© 시스템에서 발견되는 것과 같은 POSIX 호환 환경에는 단 하나의 기본 파일 유형만 존재하며, 이를 "일반 파일"이라고 부릅니다. VOS 스트림 파일 구조는 POSIX 일반 파일과 동등합니다.
VOS POSIX 런타임 환경은 4가지 유형의 파일을 모두 POSIX 일반 파일로 분류합니다. 따라서 이론상으로는 모든 POSIX 프로그램이 4가지 파일 유형을 읽고 쓸 수 있습니다. 그러나 실제로는 그렇게 간단하지 않습니다.
POSIX API는 모든 I/O 작업을 바이트 시퀀스로 정의하는 반면, VOS는 (구조화된 파일에서의) I/O 작업을 레코드 시퀀스로 정의합니다. 따라서 VOS POSIX 런타임은 사용자 공간에서 현재 레코드를 버퍼링하고, 해당 버퍼에 대해 POSIX I/O 작업을 수행한 후, 적절한 시점에 버퍼링된 레코드를 다시 기록함으로써 이러한 차이를 중재합니다.
POSIX 프로그램이 각 레코드의 크기(예: 고정 크기 파일의 경우)를 알고 있으며, 정확한 바이트 수를 읽고 쓰는 경우, 버퍼의 존재는 작업에 영향을 미치지 않으며 두 종류의 I/O 작업 간 매핑은 이해하기 쉽고 효율적이다.
그러나 POSIX 프로그램이 기본 레코드 크기를 고려하지 않고 단순히 바이트 스트림을 읽거나 쓰는 경우, POSIX 의미론과 VOS 의미론 간의 매핑은 명확히 정의되어 있지만 일반적으로 유용하지 않으며 종종 매우 비효율적입니다. 바이트 위치로 이동하거나 레코드 경계를 넘어서는 바이트 시퀀스를 재기록하는 등의 특정 작업은 최선의 경우에도 비효율적이며 최악의 경우 불가능합니다.
그리고 줄바꿈 문자 처리 문제도 있습니다.
POSIX 일반 파일과 VOS 스트림 파일 모두 레코드 경계를 구분하기 위해 줄바꿈 문자를 사용합니다. 그러나 구조화된 파일의 VOS 레코드에는 일반적으로 줄바꿈 문자가 포함되지 않습니다. 예를 들어, VOS 편집기(예: edit, emacs 또는 line_edit)가 새로운 순차 파일을 생성할 때 각 레코드는 한 줄의 텍스트를 포함합니다. 그러나 레코드는 줄바꿈 문자로 끝나지 않습니다. 관례상 모든 프로그램은 텍스트를 포함하는 순차 파일이 각 레코드 끝에 암시적 개행 문자를 갖는다고 가정합니다. 상대 파일과 고정 파일도 마찬가지입니다. 그러나 중요한 점은 다음과 같습니다: 어떤 파일(VOS, Unix, 구조화 또는 비구조화)의 속성도 해당 파일이 텍스트 데이터인지 이진 데이터인지 기록하지 않습니다. 이 구별은 파일을 접근하는 프로그램에 맡겨집니다.
이 상황은 VOS POSIX 런타임에 다소 난처한 상황을 초래합니다. 각 레코드 끝에 줄바꿈을 추가할지 여부를 판단하기 위해 VOS 구조화 파일이 텍스트를 포함하는지 데이터를 포함하는지 알아야 합니다. 파일이 텍스트를 포함하는 경우 줄바꿈을 추가해야 합니다. 데이터를 포함하는 경우 줄바꿈을 추가해서는 안 됩니다.
VOS POSIX 런타임은 호출자가 이 정보를 제공해야 한다고 가정합니다. 기본적으로 POSIX 런타임은 구조화된 파일을 텍스트를 포함하는 것으로 간주하고 줄바꿈을 추가합니다. 호출자는 O_TEXT 열기 모드를 명시적으로 지정하여 이 동작을 요청할 수 있습니다. VOS 구조화 파일을 데이터 포함 파일로 처리하려는 호출자는 O_BINARY 열기 모드를 반드시 지정해야 합니다. 이 두 모드는 상호 배타적입니다. 하나를 지정하면 다른 하나는 지정해서는 안 됩니다. 스트림 파일에는 이러한 모드가 필요하지 않으므로 이 경우에는 무시됩니다.
이 글을 읽고 계신 언어 전문가 분들을 위해 간단히 언급하자면, O_TEXT와 O_BINARY는 모두 POSIX 표준의 확장 기능입니다. POSIX 자체에 정의된 것이 아닙니다. 이들은 일반적으로 텍스트 파일과 바이너리 파일을 구분하는 운영 체제(VOS처럼)나 특별한 줄 끝 규칙을 사용하는 운영 체제(Windows처럼; CR-LF 사용)에서만 존재합니다.
정책상, Stratus가 POSIX 기반 소프트웨어를 OpenVOS로 포팅할 때 FIXED 및 RELATIVE 파일 사용을 배제하도록 수정하며, SEQUENTIAL 파일은 읽기 전용 접근으로 제한합니다. 또한 모든 순차 파일은 텍스트를 포함한다고 가정합니다. 경험상 이러한 규칙을 적용하면 POSIX 프로그램의 입력으로 STREAM 또는 SEQUENTIAL 파일을 실용적으로 사용할 수 있으며, SEQUENTIAL 출력 파일에 바이트 단위 연산을 시도할 때 발생하는 본질적인 비효율성을 피할 수 있습니다.
요약하자면, POSIX 기반 프로그램에서는 STREAM 파일(입력 또는 출력용)과 SEQUENTIAL 파일(텍스트 입력 전용)만을 사용하는 것이 최선의 접근법입니다. 구조화된 파일에 바이너리 데이터가 있다면, 이를 스트림 파일로 복사하는 작은 프로그램을 작성한 후 POSIX 프로그램에서 해당 스트림 버전 파일을 사용하십시오. FIXED 또는 RELATIVE 파일에 텍스트 데이터가 있어 POSIX 프로그램으로 처리하고자 한다면, 먼저 해당 파일을 STREAM 파일로 복사하십시오.
