Когда-нибудь здесь будет небольшая статься о вводе/выводе в системе UNIX. :-) Пока же читатель может посмотреть кучу специальной литературы. Например :
Робачевский А.М.
"Операционная система Unix"
СПб. Издательство BHV
Санкт-Петербург, 1997
ISBN 5-7791-0057-8Andrei Robachevsky
Federal Centre RUNNet
e-mail: andrei@run.net
phone: +7-812-2388598
fax: +7-812-2327622
http://www.runnet.ru
Здесь же кратко коснемся только проблем локализации ввода/вывода UNIX.
Итак, цитируем :
В UNIX существуют 6 типов
файлов, различающихся по функциональному
назначению и действиям операционной системы при
выполнении тех или иных операций над файлами :
|
Продолжаем цитировать :
Из этого следует, что в общем случае не существует никакого способа узнать не только кодировку, но даже тип данных, содержащихся в файле.
В принципе, существуют два основных способа определения содержимого файла (набора/потока данных) :
Самый известный In-band способ - MIME. Здесь кодировки и вид содержимого описываются явно, в полях Content-Type: text/plain; charset=koi8-r и Content-Transfer-Encoding: base64. Концепции MIME (описание типа) используются также в HTTP (RFC-2616).
Также In-band сведения о содержимом и кодировках содержатся, например, в файлах Microsoft Word .DOC(с включенными OLE объектами), Windows .EXE и .DLL (ресурсы), e.t.c. К In-band методам можно отнести и разнообразные языки разметки (MARK-UP Languages), например тэг <LANG=> языка HTML 4.0 и XML или спецификацию языка в файлах .RTF.
Теперь об Out-band (внешних) способах. К сожалению, в UNIX поддерживается простая однопотоковая концепция организации файла. Нет никаких ресурсных вилок, как в MacOS HFS, нет Meta Info как в OS/2 HPFS. Файл - это просто набор данных, имеющий имя (ну, еще даты создания/изменения/доступа, ну еще права доступа : rwxr-xr-x ). Без всяких "расширенных атрибутов".
Проблема зашла так далеко, что в UNIX появилась специальная утилита file, которая "эвристическими методами" пытается определить тип содержимого.
Единственный более-менее распространенным способом определения типа файла является расширение, то есть несколько конечных символов в имени файла после точки : ".txt". На самом деле, никакого стандарта на "расширения" в UNIX нет, так как точка : "." является допустимым символом имени. Так что вполне могут встретится имена типа "file.doc.tar.gz", "file............txt" или ".profile".
Тем не менее, многие программы ориентируются именно на "расширения", особенно при переводе в MIME, например для простановки типа в HTTP (RFC-2616):
Насколько ненадежен этот метод, можно судить например по тому, что текстовый (!) файл "ls-lR.ftp.anu.edu.au" упорно интерпретируется как "audio/basic" и некоторые программы пытаются его "сыграть" ;-))
Тем не менее, иногда этим можно пользоваться, например задавая определения типов (и многие другие атрибуты) для файлов текущего каталога, в файле ./.htaccess от apache ( модуль mod_mime ):
AddType text/plain text AddEncoding x-compress Z AddIconByType (TXT, icons/text.gif) text/plain AddIconByEncoding (COMP, icons/comp.gif) application/x-compress e.t.c. |
Ну чем не Out-band метод ? Правда доступ к файлу в таком каталоге осуществлять придется только через HTTP от apache. ;-)
Но продолжаем цитировать :
Файл в файловой системе имеет некоторое имя - последовательность символов. Когда-то считалось, что имя файла может состоять только из 7-bit ASCII символов. В случае же использования национальных символов для имени файла возникают проблемы. И в стандарте POSIX решения нет.
Существующие способы определения кодировки символов в имени файла :
Все операции, оперирующие с именами файлов должны быть как минимум прозрачны в отношении 8 бит.
Блочные файлы устройств позволяют организовать доступ к физическому устройству точно также, как доступ к обычному файлу. И точно также, как при работе с обычным файлом, интерпретация содержимого остается задачей программы. Никакой информации о кодировках содержимого не поддерживается.
Более неприятна ситуация с симольными (character) устройствами, где также совершенно не существует определения character set. Другими словами, стандартными средствами UNIX (POSIX) невозможно ни определить текущую, ни установить необходимую кодироку символьного устройства (например, терминала).
Стандартных средств изменения и определения кодировки нет ни для "настоящих" (подключенных через ASYNC-port) терминалов , ни для эмуляторов консоли (SCO, BSD или LINUX console), ни для окна xterm в X-Windows (работающих через псевдотерминалы /dev/pty). Понятий "кодировка" или "набор символов" нет ни в процедурах управления терминалом : termios (POSIX), ни в базах описания терминалов termcap и terminfo, ни даже в "высокоуровневых" библиотеках управления терминалом curses и ncurses. (TODO: посмотреть slang ).
Точно также, нет указателя Charset у потоков STDIN, STDOUT, STDERR.
* ПРИМЕЧАНИЕ: В настоящее время наметилось несколько путей решения этой проблемы:
FIFO или именованый канал - это файл, используемый для связи между процессами. FIFO впервые появились в System V UNIX, но большинство современных систем поддерживают этот механизм. |
Не вдаваясь в тонкости отличий System V и BSD, скажем о FIFO следующее :
Собственно, на имя связи и на ее содержимое распространяются те же правила, что и на имя в Каталоге.
Сокет. Сокет представляет собой двусторонний канал обмена данными между процессами и является одним из механизмов IPC (Inter-Process Communication). |
Механизм сокетов был разработан для унификации межпроцессорного взаимодействия и должен был работать независимо от :
Для описания характеристик взаимодействия было введено понятие коммуникационный домен (communication domain). Сокеты создаются в рамках определенного коммуникационного домена, и, кроме прочих характеристик, имеют соответствующее имя (связываемое с сокетом при помощи вызова bind() ).
Не вдаваясь в подробности функционирования Socket API, рассмотрим лишь отношение сокетов и методов кодирования передаваемой информации.
Сокеты (stream socket), после установления соединения предоставляют процессам чистый 8-ми битный канал обмена информацией (Out-Of-Band данные не рассматриваются). В принципе, пользователь может передавать данные в совершенно произвольном формате. Однако, существуют некоторые "устоявшиеся правила" организации протоколов обмена данными (IPC).
1. Разделять управляющую информацию и пользовательские данные. Как сказано в RFC-2277 "Srtings for humans, Protocols for computers".
2. Текстовый управляющий протокол - это "правильная вещь". (c) Eric S. Raymond, разработчик fetchmail. Для облегчения разработки и сопровождения протокола, управляющие команды и ответы сервера лучше сделать в виде текстовых строк.
3. Хорошо разработанный протокол содержит в себе созможности Handshake (или Negotiation)
- Language Negotiation, например, поля
Accept-Language:
Content-Language:- Type & Charset Negotiation, например, поля
Accept:
Accept-Charset:
Content-Type: text/plain; charset=
Content-Type: text/html; charset=- Transfer Encoding Negotiation
Accept-Encoding:
Content-Transfer-Encoding:См. например один из документов проекта Multiweb.
Если у вас имеются каие-либо дополнения или исправления, пишите mailto:alec@sensi.org
--
-=AV=-
Содержание "Locale AS IT IS"