컴퓨터과학/운영체제

[운영체제] 파일의 개념

PureStack 2021. 12. 28. 00:53

파일이란?

  • 보조 기억 장치에 기록되어 있는 관련된 정보들의 집합체
  • 사용자 관점에서, 파일은 논리적 보조 저장 장치에서의 최소 할당 단위
  • 파일 내부의 정보는 작성자에 의해 정의되며, 다양한 정보들이 파일 내에 저장된다.
  • 운영체제는 논리적인 저장 단위를 디스크와 같은 물리적 저장장치에 매핑하여 저장된다.

대표적인 파일의 종류

  • text file: 사람이 인지할 수 있는 문자열 집합으로부터 문자열로만 이루어진 파일
  • source file: 실행해야 할 소스 문장들의 구성으로 이루어져 있으며 서브루틴이나 함수들의 집합체
  • executable file: 코드화된 명령에 따라 지시된 작업을 수행하도록 하는 컴퓨터 파일

파일의 속성

사용자의 편의를 위해 파일에 이름이 부여되고 그 이름은 문자열로 이루어져 있다. 파일의 속성들은 운영체제마다 상이하지만 전형적으로 이러한 요소들로 구성되어 있다.


  • 이름 (Name) : 사람이 읽을 수 있는 형태로 유지된 기호형 파일 이름
  • 식별자 (Identifier) : 보통 숫자로 파일 시스템 내에서 파일을 확인한다. 파일의 이름은 인간이 읽을 수 없는 형식이다.
  • 종류 (Type) : 다른 종류의 파일들을 지원하는 시스템에 요구되는 정보들이 있다.
  • 위치 (Location) : 장치와 장치의 파일 위치를 가리키는 포인터에 대한 정보이다.
  • 크기 (Size) : 파일의 현재 크기와 최대 허용 크기가 이 속성에 포함되어 있다.
  • 보호 (Protection) : 접근 제어 정보는 읽기, 쓰기, 실행 등등을 할 수 있는 사용자를 결정한다.
  • 타임스탬프와 사용자 식별 (Timestamps and user identification) : 생성, 마지막 수정, 마지막 사용에 관한 정보를 담고 있다. 이 데이터들은 보호, 보안, 그리고 사용 모니터링에 유용하다.

파일의 연산

파일은 추상적인 데이터 유형이다. 파일을 적절하게 정의하기 위해서 우리는 파일에서 수행될 수 있는 연산들을 고려할 필요가 있다. 운영 체제는 생성, 쓰기, 읽기, 위치 재설정, 삭제, 그리고 파일 자르기의 시스템 호출 함수들을 제공한다.


  • 파일 생성 (Creating a file) : 두 단계가 필요한데, 첫 번째로 파일 시스템 내에서 파일을 위한 공간을 찾은 후, 두 번째로 새로 생성된 파일에 대한 항목이 디렉토리 안에서 형성되어야 한다.
  • 파일 열기 (Opening a file) : 파일 생성과 삭제를 제외한 나머지 연산들에게 맨 처음 요구되는 시스템 호출 함수이다. 만약 성공한다면, open 함수는 파일 핸들(파일 디스크립터, 파일 기술자)을 반환한다. 파일 기술자는 부호가 없는 정수로 하나의 프로세스에서 파일 입출력을 수행하는 단위마다 유일한 번호를 보장한다.
  • 파일 쓰기 (Writing a file) : 파일에 쓰기 위해, 파일 이름과 파일에 쓰여진 정보들을 명시하는 시스템 호출 함수를 실행한다. 시스템은 파일 내에서 다음 쓰기가 일어날 위치를 파악하는 쓰기 포인터(write pointer)를 유지해야 한다. 쓰기 포인터는 쓸 때마다 갱신된다.
  • 파일 읽기 (Reading a file) : 파일을 읽기 위해, 파일 이름과 파일이 읽혀져야 할 블록의 위치를 명시하는 시스템 호출 함수를 실행한다. 시스템은 다음 읽기가 어디서 진행되는지에 대한 위치 정보를 지닌 읽기 포인터(read pointer)를 유지할 필요가 있다. 읽기가 진행되면, 읽기 포인터는 업데이트된다. 프로세스는 보통 파일 읽기나 쓰기 중 하나를 하고 있으므로, 대부분의 시스템은 하나의 현재 파일 위치 포인터(current-file-position pointer)를 가지고 있다.
  • 파일 내의 위치 재설정 (Repositioning within a file) : 열려 있는 파일의 현재 파일 위치 포인터를 주어진 값으로 설정한다. 파일 내의 위치 재설정은 실제 입/출력을 할 필요가 없으며, 이 연산은 파일 탐색(seek)으로도 알려져 있다.
  • 파일 삭제 (Deleting a file) : 파일을 삭제하기 위해, 연관된 디렉터리를 탐색한다. 연관 디렉터리 엔트리를 찾은 후, 파일의 모든 공간을 해제하여 다른 파일들이 재사용할 수 있게 한다. 몇몇 시스템은 하드 링크(hard link)를 허용하는데, 같은 파일에 대해 여러 개의 이름들을 생성하는 것이다. 이러한 경우에, 실제 파일 정보는 마지막 링크가 없어질 때까지 삭제되지 않는다.
  • 파일 자르기 (Truncating a file) : 사용자가 파일의 내용은 지우지만 그 파일의 속성을 유지하길 원할 수도 있다. 사용자가 그 파일을 삭제하고 다시 만드는 것이 아니라 파일 길이를 제외한 모든 속성은 그대로 유지하게 하는 기능이다. 그 파일은 길이가 0으로 재설정 될 수 있고 그 파일 공간은 해제될 수 있다.

오픈 파일 테이블 (open-file table)

파일 연산을 하면 디렉터리를 찾는 작업을 수행하기 때문에 열기 연산을 한 파일들의 정보를 저장함으로써 쓸데없는 연산의 양을 줄인다. open() 시스템 호출 함수를 실행하면 해당 테이블 항목에 대한 포인터를 반환하고, 이를 통해 입출력 연산에 사용하게 된다.


  • 파일 포인터 (File pointer) : read()와 write() 시스템 호출 함수의 일부분으로 파일 오프셋을 포함하지 않는 시스템은 현재 파일 위치 포인터를 통해 마지막 읽기/쓰기 위치를 추적해야 한다. 이 포인터는 파일 연산을 수행하는 각 프로세스에 하나씩 만들어지므로 디스크 상의 파일 속성들과 분리되어야 한다.

  • 파일 오픈계수 (File-open count) : 파일이 닫히면, 운영 체제는 오픈 파일 테이블의 엔트리(항목)들을 재사용해야 하며, 그렇지 않으면 테이블 내의 공간이 부족해질 것이다. 여러 프로세스들은 열린 파일들을 가지고 있고, 시스템은 오픈 파일 테이블 엔트리들이 제거되기 전에 마지막 파일이 닫힐 때까지 기다려야 한다. 파일 오픈 계수는 열기와 닫기의 개수를 추적하며 계수 값이 0에 도달하면 시스템은 이때 엔트리를 제거할 수 있다.

  • 파일의 위치 (Location of the file) : 대부분 파일 연산들은 시스템에게 파일 내의 데이터들을 읽거나 쓰기를 요구한다. 디스크 상의 파일 위치를 찾기 위한 정보는 매 연산마다 디스크로부터 읽는 것을 피하기 위해 메모리에 저장된다.

  • 접근 권한 (Access rights) : 각 프로세스는 파일을 하나의 접근 모드로 연다. 그 정보는 각 프로세스 테이블에 저장되어 있으며 운영체제는 이 정보를 후속 입출력 요청을 허용하거나 부정하는데 이용할 수 있다.

파일의 구조 (File Structure)

  • 파일 유형은 파일의 내부 구조를 나타내는데 이용될 수 있다. 경우에 따라 운영체제가 인식 가능하도록 정해진 구조를 따르게 할 수 있다.
  • 운영체제가 여러 개의 파일 구조를 지원하는 경우의 단점은 운영 체제의 크기가 증가한다는 것이다. 만약 운영체제가 5개의 다른 파일 구조들을 정의한다면, 이 파일 구조들을 지원하기 위한 코드들이 포함되어 있어야 한다. 게다가, 모든 파일은 운영 체제가 지원하는 파일 유형들 중 한 종류의 유형으로만 정의되어야 한다.
  • 몇몇 운영 체제들은 파일 구조에 대하여 최소한도의 제한만 둔다. 이러한 접근 방식은 유닉스, 윈도우, 그리고 다른 운영체제들에 적용되고 있다. 이러한 접근 방식은 최대의 유연성을 제공하지만 시스템 차원에서 파일 유형 지원은 상대적으로 적다.
  • 모든 운영 체제는 적어도 한 가지 파일 구조는 지원해야 한다. 그렇게 해야 시스템이 프로그램을 가져오고 실행할 수 있다.

내부 파일 구조 (Internal File Structure)

  • 디스크 시스템은 전형적으로 섹터의 크기에 의해 결정되는 블록 크기를 가진다. 모든 디스크 입출력은 한 블록 단위로 실행되며 모든 블록들은 같은 크기를 지닌다. 논리 레코드의 길이는 매우 다양하며, 논리 레코드를 하나의 물리 레코드에 패킹하는 것이 일반적이다.
  • 논리 레코드의 크기, 물리 블록 크기, 패킹 기술은 얼마나 많은 논리 레코드들이 각 물리 블록에 들어갈 것인지를 결정한다. 패킹은 사용자의 응용 프로그램이나 운영 체제에 의해 실행된다. 모든 기본적인 입출력 기능들은 블록의 관점으로 수행된다.
  • 디스크 공간은 항상 블록 단위로 할당되므로, 각 파일의 마지막 블록 몇몇 부분은 일반적으로 낭비된다. 각 블록이 512 byte라면, 1949 byte 크기의 파일은 4블록이 할당될 것이며 마지막 99byte는 낭비된다. 이런 식으로 낭비되는 현상을 내부 단편화(Internal Fragment) 라고 한다. 모든 파일 시스템은 내부 단편화의 문제점을 지니고 있으며, 블록 크기가 클수록 내부 단편화 문제는 심각해진다.