Как уже говорилось, все, что существует
Помнится, на заре моего приобщения к компьютерам этот вопрос доставил мне немало пищи для размышлений. Встреченное где-то (не у Фигурнова ли?) определение файла как именованной области на диске для хранения данных казалось а) интуитивно непонятным, и б) не соответствующим собственным впечатлениям. И по мере освоения POSIX-систем (сначала Linux'а, а потом и BSD) оказалось, что интуиция меня не подвела. Ибо файл - это отнюдь не область, расположен он не всегда на диске и уж ни в коей мере не привязан к какому-то имени.
В самом общем виде файл можно определить (хотя это - лишь мое скромное мнение) как некую последовательность байтов, идентифицируемую тем или иным образом. Причем имя файла, как скоро станет ясным, отнюдь не единственный и даже не главный способ его идентификации. А то, где хранится эта самая байт-последовательность, и какая именно информация передается теми самыми байтами, - дело уже десятое.
Предложенное определение может быть применено к любой операционной системе. Конкретно же в Unix'ах всякого рода (сиречь POSIX-совместимых ОСях) к этому следует прибавить, что файл состоит как бы из двух частей, не обязательно находящихся в одном месте (а в общем случае - как раз разобщенных).
Первая часть файла - так называемая область метаданных, именуемая по английски inode (index node или information node - мне встречались обе расшифровки). Нормального русского эквивалента для этого термина не придумано (выражения типа "информационный узел" вряд ли прояснять существо дела, а "индексный дескриптор" назвать русским выражением трудно), и потому далее он будет использоваться без перевода. В inode содержатся некоторые сведения о файле (именуемые атрибутами файла), как то:
Все эти характеристики файла будут рассмотрены в следующих параграфах этого раздела.
Область данных файла заключает в себе собственно ту информацию, для хранения которой файл и предназначен.
Она может быть самой различной - текстовые символы, двоичные коды и многое, многое другое. Однако характер этой информации для операционной системы POSIX-типа безразличен (чего нельзя сказать о пользовательских приложениях) - она воспринимает их просто как последовательность байтов.
Область данных не является непременной принадлежностью файла. Существуют файловые системы, которые умудряются разместить данные маленьких файлов в области метаданных, чем достигается как быстрота доступа к хранимой информации, так и экономия дискового пространства. Потому что, не смотря на приведенную выше оговорку, файлы в основном все же хранятся на дисковых устройствах.
Внимательный читатель, привыкший под влиянием DOS/Windows к трактовке файлов в качестве именованных документов, обратил внимание на то, что среди атрибутов файлов нет одного, казалось бы, самого важного, - имени файла. Как же различаются они друг от друга?
Цели идентификации файлов служат числа, которые, как это ни странно, так и называются - идентификаторы. Таковых - два: идентификатор устройства и собственно идентификатор файла. Со вторым все более-менее понятно - это просто порядковый номер (с некоторыми оговорками). И номер этот - уникален для файловой системы. Именно по нему ОС считывает информацию из конкретного файла - то есть из области его данных, поставленных в однозначное соответствие с файловым ID из inode.
А понятие идентификатора устройства требует некоторого пояснения. Когда речь шла об установке системы (), вскользь было упомянуто о том, что Linux или BSD могут быть установлены на несколько дисковых разделов. И каждый из этих разделов будет нести свою файловую систему, образующую отдельные ветви единого файлового древа.
Так вот, нумерация файлов в каждом таком разделе - независима от других, начинаясь с 2 (идентификатор "локального" корня). И потому в каждой ветви файловой системы могут быть (и неизбежно будут) файлы с одинаковыми идентификаторами. Чтобы отличать их друг от друга, и введен такой атрибут - идентификатор устройства.
Файлы существуют в том числе и для того, чтобы пользователь с ними работал - открывал, просматривал, редактировал, и т.д. А из мы уже знаем, что все эти действия осуществляются процессами. То есть каждый процесс имеет некий набор открытых им файлов. Однако легко представить себе ситуацию, при которой два и более процессов открывают один и тот же файл. Как они различаются? - ведь inode открытого файла по определению один, а имя файла в контексте процесса также не фигурирует.
Для этой цели предназначены т.н. файловые дескрипторы, которые не следует путать с дескрипторами индексными (сиречь inodes). Файловые дескрипторы (в дальнейшем условимся называть их дескрипторами просто) - это также числовые идентификаторы, которые присваиваются файлам по мере открытия их данным процессом. Причем нумерация их для каждого процесса - отдельная. То есть файл с inode xxx, открытый процессом A, получит дескриптор M, а в процессе B ему же будет присвоен дескриптор N.
Однако одинаковые дескрипторы для одних и тех же файлов также не запрещаются. Примером чему - имеющие особое значение имеют дескрипторы 0, 1 и 2. В любом процессе они присваиваются фиксированным файлам устройств - стандартного ввода, стандартного вывода и стандартного потока ошибок (/dev/stdin, /dev/stdout, /dev/stderr, соответственно). К ним мы еще вернемся, а пока достаточно запомнить, что в случае настольной персоналки для ввода данных в процесс стандартно служит устройство под названием "клавиатура", а вывод процесса осуществляется на экран монитора (куда по умолчанию валятся и все сообщения об ошибках).