Добавить в избранное | Сделать стартовой страницей

Большая Linux библиотека для пользователей OS Linux и ПО для нее
Есть что сказать? Нужен совет? Посети наш форум.




Типы файлов: введение.

Автор : Дмитрий Карпов

Как известно всем, кто занимался этим вопросом, информация обычно хранится на магнитных, а также на магнито-оптических и оптических носителях - жестких и сменных дисках. Жесткие диски и дисководы CD-ROM в большинстве имеют интерфейс IDE, реже - SCSI; дисководы используют интерфейс {MFM}; съемные дисководы типа Iomega ZIP помимо IDE и SCSI нередко подцепляются через LPT или COM-порты; в особо ответственных случаях используется энергонезависимая Flash-память. Все эти интерфейсы предельно примитивны и обеспечивают прямой доступ на наивозможно низком уровне для предоставления максимальной гибкости программному обеспечению (операционной системе) в размещении информации.

/* С одной стороны, мне бы хотелось, чтобы диск взял на себя больше работы; с другой стороны, учитывая современные тенденции, наверняка производители с самого начала реализовали бы самые примитивные схемы, а потом ради совместимости никто бы не решился что-либо изменить. Например, из-за такой совместимости диск IDE вынужден скрывать свою истинную конфигурацию, притворяясь, что у него на каждом треке одинаковое количество секторов. */

Все эти интерфейсы весьма неудобны как для пользователя, так и для программиста - в них нет ни учета занятого/свободного места, ни предоставления доступа по имени (во всех этих интерфейсах используется числовая адресация); к тому же в большинстве из них доступ производится только блоками размером от 256 до 8192 байт (по степеням двойки). Чтобы предоставить программисту и пользователю более удобный интерфейс, в меньшей степени зависящий от физической природы носителя, практически во все операционные системы включен такой компонент, как драйвер файловой системы (да обычно и не один, а несколько).

Технология современных файловых систем пошла от Unix: файл является набором байтов, которые можно читать как поодиночке, так и (что гораздо быстрее) пачками.

/* Для тех, кто интересуется историей, могу сообщить, что более древние файловые системы были организованы как базы данных, так что файл состоял из отдельных записей. Желающие могут посмотреть организацию работы с файлами в языке Fortran - она явно наследует принципы тех машин, на которых создавался Fortran. Многое оттуда унаследовано и языком Pascal, а вот язык C Кернигана и Ритчи имеет все признаки того, что он - радной для Unix. */

Но помимо данных, собственно содержащихся в файле, хотелось бы знать, для чего предназначены эти данные, как с ними можно обращаться.

Прежде всего, в любой файловой системе существуют два типа файлов:

  1. обычные, доступные программам напрямую;
  2. директории, содержащие списки других файлов и их атрибутов (списки, но не сами файлы), доступные только операционной системе (впрочем, ряд атрибутов доступен программам только-для-чтения, а то и для-изменения, но никак не напрямую);

плюс к тому в некоторых системах существуют специальные файлы, через которые осуществляется доступ к устройствам компьютера; в DOS примером могут быть файлы COM?, LPT?, PRN, CON, а в Unix - все файлы в директории /dev/.

Данные, содержащиеся в обычных файлах, тоже могут быть различны. Нередко тип данных можно определить прямо по их формату. Простейшая класификация:

  • текстовые:
    • семибитные - содержат только символы с кодами от 0x20 до 0x7E, а также знаки конца строки и табуляции;
      знаки с кодами от 0x00 до 0x1F и 0x7F Delete считаются непечатными;
      вдобавок к этому конец строки на разных платформах различается -
      • Unix использует 0x0A,
      • Acorn и Apple - 0x0D,
      • DOS и Windows - пару 0x0D+0x0A, хотя многие программы понимают и эти символы по отдельности;
    • восьмибитные - дополнительно к семибитным содержат символы с кодами от 0x80 до 0xFF;
      вторая половина алфавита может интерпретироваться по разному в зависимости от используемого языка и кодировки (для руского языка есть аж пять кодировок);
    (вообще-то текст должен иметь еще ограничения на длину строки - желательно не выходить за 80 символов (ширина большинства текстовых экранов), а если не получается - то за 128, 256 или хотя бы 4096 символов);
  • двоичные - все, которые не текстовые.
    хотя если случайно двоичные данные будут содержать только символы, разрешенные в текстовых форматах, это еще не значит, что с ними можно обращаться как с текстом.
В виде текста хранятся многие форматы - собственно текст, HTML, LaTex, программы на языках Basic, C, Fortran, Pascal и многих других, файлы редактора ChiWriter, почтовые сообщения (обычно формат MIME), /.../; а уж разнообразие двоичных форматов и вовсе неичислимо. Иногда формат файла можно угадать по его структуре или сигнатуре (характерному признаку, обычно специально внесенному в формат файла), но все это недостоверно (например, может оказаться, что файл, содержащий набор случайных чисел, содержит любую сигнатуру); так что хотелось бы иметь более четкий критерий. В Unix имеется утилита file, которая по содержимому файла (хотя, возможно, привлекаются соображения, основанные на имени файла и атрибутам доступа) на основании некоторых эмпирических правил определяет и сообщает пользователю тип файла.

Ситуация осложняется тем, что многие операционные системы должны работать с несвойственными для них файловыми системами имея прямой доступ к диску с неродной файловой системой или имея по сетИ доступ к серверу. При этом воникают проблемы уже на уровне имен файлов:

  • Одни операционные системы считают прописные и строчные буквы разными (Unix); другие учитывают разницу между ними при создании файла, но игнорируют при дальнейших обращениях (Acorn, Windows'9x/NT); третьи приводят имя файла к прописным буквам (CP/M, DOS).
  • В разных операционных системах имеется разный набор символов, допустимых в имени файла. Во всех системах допустимы латинские буквы, цифры и подчеркивание '_'.
  • Максимально допустимая длина имени файла в разных файловых системах разнлича.
    При несовпадении максимально допустимых длин или наличии "неподходящих" символов производится либо усечение имени, либо замена по определенному алгоритму (наиболее распространеная замена: последние несколько символов заменяются на тильду и номер либо на тильду и hash-функцию имени).
Кроме того, каждая файловая система имеет свои атрибуты доступа к файлам, зависящие от стратегии распределения прав пользователей, и свои дополнительные атрибуты, зависящие от фантази авторов систеы. Обычно разработчики стараются транслировать права доступа к файлу (перевести в формат, используемый в данной операционной системе) по определенным правилам
    Например, Unix имеет правА на чтение, запись и запуск для хозяина, для группы и для всех остальных; в DOS и Windows'9x при доступе по сетИ транслируются
    1. в атрибут 'read-only' право на запись в соответствии с пользователем и его группой, под которым клиент DOS/Windows подсоединисля к серверу
    2. и в атрибут 'hidden' - наличие точки в начале имени файла.
    Бывают и более сложные правила трансляции в зависимости от типа файла.

    Простейший и наиболее универсальный (наименее платформенно-зависимый) способ состоит в том, чтобы зафиксировать тип данных в имени файла - имя ведь передается всегда и по возможности с наименьшими искажениями. По традиции тип файла отображают по возможности осмысленной аббревиатурой в конце имени файла, называемой "расширением имени файла" ("filename extension"), и для отделения используют точку '.' /* AcornOS, которая использует точку как разделитель имен директорий, там где Unix использует прямой слэш '/' а DOS/Windows - обратный '\', позволяет использовать вместо точки прямой или обратный слэш, но никто, кроме DOSFS, позволяющей работать с FAT-дискетами, не рассматривает слэши как разделители. */ Чаще всего стараются обойтись тремя символами в аббревиатуре; в RSX-11, CP/M и FAT это зафиксировано непосредственно в формате хранения имени файла, где точка является спец.символом, может присутствовать в имени файла только один раз - между основным именем и расширением, и не хранится в имени файла, а "вытекает из формата имени". В UFS (Unix), HPFS (OS/2), NTFS (Windows'NT) и NetWare нет такого ограничения, там точка является обычным символом имени файла, а ее специфическое значение распознается прикладными программами, если программист реализовал это в своей программе, но не отображается в формате файла. В VFAT работа с "длинными именами", не влезающими в формат "8.3" ("восемь букв на имя, точка, три буквы на расширение"), реализована довольно искусственно, для сохранения доступа программ, использующих простой FAT, в директории хранятся два имени - "короткое 8.3" и "длинное".

    Иногда данные, имеющие какой-либо тип, последовательно "упаковываются" несколькими архиваторами; в этом случае возникают такие расширения как .tar.gz, обозначающее архив tar, подвергнутый gzip-компрессии (часто встречается в Unix), или .c.zip.uue, обозначающее пограмму на языке C, заархивированную программой zip и преобразованную uuencode для передачи по электронной почте без присущих ей искажений (выдумано мной для примера).

    Я составил справочник соответствия расширений типам файлов по собственному опыту, литратуре и подсказкам заинтересованных посетителей моей страницы. Коллекция продолжает пополняться, и Вы можете принять в этом участие.

    Основным недостатком использования расширений имени файла является как раз то, что тип файла определяется по имени файла

    1. Достаточно нелогично, что операция переименования влияет на атрибут, обозначающий тип содержимого - это провоцирует ошибки пользователей, вызванные опечатками при наборе на клавиатуре. Из-за такой ошибки файл может пропасть из списков, составляемых по типу файла, или, хуже того, появитьсмя в другом списке и вызвать проблемы в работе программ, полагающихся на расширение файла. Фактически раз переименование файла .koi.html в .win.txt не переводит файл из кодировки KOI8-r в Win1251 и из HTML-формата в простой текст, это является нарушением целостности данных; такие вещи допустимы в экстремальных случаях (когда администратор вынужден "лезть под капот" и вручную исправлять сбой), но недопустимо предоставлять любой программе, а тем более любому юзеру возможность без труда менять расширение имени файла без соответствующего изменения содержимого!
    2. Часто одно и то же расширение используется для совершенно различных типов файлов. Примером может служить .doc, обозначающий как просто документацию, так и файлы несовместимых между собой версий MS-Word для DOS, Windows'3.x (версии до шестой) и Windows'9x/NT (начиная с седьмой, именуемые также по году выпуска).

    В Unix запускаемые файлы имеют специальный атрибут. Вообще говоря, транслировать этот атрибут другим операционным системам, даже Unix'ам и даже другим версиям того же Unix'а (особенно если отличаются первые цифры версий) довольно опасно - Unix-совместимость гарантирована только на уровне исходного кода и требует перекомпиляции. Формат двоичных запускаемых файлов никогда не бывает текстовым#, поэтому его нельзя перепутать с со скриптами - интерпретируемыми программами. Чтобы скрипт интерпретировался именно нужным интерпретатором, в его начало помещаетя строка

       #!/путь/shell [ключи]
    
    которая определчяет тип скрипта (наиболее распространенные - sh, csh и прочие варианты командной оболочки, а также perl; особо одаренные, бывает, используют awk). Серьезный недостаток этого метода в том, что интерпретатор может находиться не в том месте, где его ожидал автор скрипта, или начинаются проблемы с версией интерпретатора, явно указанной в имени файла.

    Acorn и Macintosh (Apple) используют специальное поле, в котором записывается в числовом виде тип файла. Чтобы разные авторы форматов файлов не вступали в противоречие друг с другом, используя одно и то же число для обозначения разных форматов, обе фирмы ведут учет используемых типов и если программист хочет, чтобы его программа беспроблемно использовалась широкими слоями юзеров, он должен зарегестрировать придуманный им тип данных, получив для него идентификатор. /* Аналогично Acorn распределяет системные вызовы SWI.*/ Macintosh имеет сструктуру типа ACL в NTFS, но хранит там не права доступа, а информацию о типе данных; Acorn использует два четырехбайтных поля, использовавшиеся в 8-битных машинах для информации об адресе загрузки и адресе запуска программы.

    Сетевой протокол HTTP использует свой способ сообщить клиенту тип передаваемых данных (я сознательно говорю "тип данных", а не "тип файла" - передаваемые данные могут не содержаться в файле, а формироваться непосредственно по запросу). Способ называется MIME и используется во многих других местах, в частности, в электронной почте. Формат MIME довольно прост: в начале идет заголовок, состоящий из строк

      имя_параметра: значение [атрибуты]
    
    затем пустая строка и собственно данные. В HTTP обязательно (а для другие могут обойтись и без этого) должна присутствовать строка
      Content-Type: тип/подтип
    
    определяющая тип данных. Если тип - text, то в атрибутах часто передается кодировка, особенно если документ составлен на языке, использующем не латиницу, а собственный алфавит. Многие почтовые программы прямо жить не могут без
     MIME-Version: 1.0
    
    Особо мне хочется отметить вариант
      Content-Type: multipart/подтип; boundary="строка"
    
    где подтип - alternative (части содержат одно и то же в разных форматах) или mixed (совокупность данных разного формата), а "строка" обычно что-нибудь типа "----=_NextPart_000_0037_01BE808E.D9AC1F40" - уникальная для данного документа последовательность символов, не встречающаяся нигде, кроме разделителей. Разделителями являются
           --строка
    
    а в конце всего идет
            --строка--
    
    Каждый из разделов сам оформлен в формате MIME, разве что не требует "MIME-Version:", так что может в свою очередь содержать multipart данные.

    Остался непроясненным вопрос о том, откуда составитель MIME-документа узнает о том, к какому типу относятся включенные в документ данные.

    • Если документ составляет программа в ответ на запрос (например, CGI-скрипт), то тип данных должен быть известен программисту - должен же он знать, что посылает!
    • Если данные берутся из файловой системы (как это делают Web-сервер или почтовая программа при составлении Attachment), то информация о типе данных обычно берется из файловой системы. Наиболее распространенными являются системы на базе Unix и Windows'9x/NT - они обычно ориентируются на расширение имени файла (например, Apache использует файл ".../conf/mime-types", в котором записано соответсвтие Content-Type: каждому известному ему расширению).


    Ссылки:

    • Tim Kentzle, "Форматы файлов Internet", изд-во ПитерПресс.
    • Описание множества форматов файлов на английском языке - www.wotsit.demon.co.uk (www.wotsit.org).

    Программы для работы с графикой:

    • Конвертор граф.форматов Alchemy.
    • Редактор изображений LView.
    • Генератор изображений Fly.
    • GIF Shaker; Ulead SmartSaver.
    • Оптимизатор JPEG-графики WebOpt.

    Обсудить данную тему на нашем форуме "Все о Linux"