System/Docu/ru/Files.odc

Files
ENGLISH
Редакция перевода: Ф.В.Ткачев, 2010-10-25

DEFINITION Files;

	CONST
		exclusive = FALSE; shared = TRUE;
		dontAsk = FALSE; ask = TRUE;
		readOnly = 0; hidden = 1; system = 2; archive = 3; stationery = 4;

	TYPE
		Name = ARRAY 256 OF CHAR;
		Type = ARRAY 16 OF CHAR;

		FileInfo = POINTER TO RECORD
			next: FileInfo;
			name: Name;
			length: INTEGER;
			type: Type
			modified: RECORD
				year, month, day, hour, minute, second: INTEGER
			END;
			attr: SET
		END;

		LocInfo = POINTER TO RECORD
			next: LocInfo;
			name: Name;
			attr: SET
		END;

		Locator = POINTER TO ABSTRACT RECORD
			res: INTEGER;
			(l: Locator) This (IN path: ARRAY OF CHAR): Locator, NEW, ABSTRACT
		END;

		File = POINTER TO ABSTRACT RECORD
			type-: Type;
			(f: File) Length (): INTEGER, NEW, ABSTRACT;
			(f: File) NewReader (old: Reader): Reader, NEW, ABSTRACT;
			(f: File) NewWriter (old: Writer): Writer, NEW, ABSTRACT;
			(f: File) Flush, NEW, ABSTRACT;
			(f: File) Register (name: Name; type: Type; ask: BOOLEAN; OUT res: INTEGER), NEW, ABSTRACT;
			(f: File) Close, NEW, ABSTRACT;
			(f: File) InitType (type: Type), NEW
		END;

		Reader = POINTER TO ABSTRACT RECORD
			eof: BOOLEAN;
			(r: Reader) Base (): File, NEW, ABSTRACT;
			(r: Reader) Pos (): INTEGER, NEW, ABSTRACT;
			(r: Reader) SetPos (pos: INTEGER), NEW, ABSTRACT;
			(r: Reader) ReadByte (OUT x: BYTE), NEW, ABSTRACT;
			(r: Reader) ReadBytes (VAR x: ARRAY OF BYTE; beg, len: INTEGER), NEW, ABSTRACT
		END;

		Writer = POINTER TO ABSTRACT RECORD
			(w: Writer) Base (): File, NEW, ABSTRACT;
			(w: Writer) Pos (): INTEGER, NEW, ABSTRACT;
			(w: Writer) SetPos (pos: INTEGER), NEW, ABSTRACT;
			(w: Writer) WriteByte (x: BYTE), NEW, ABSTRACT;
			(w: Writer) WriteBytes (IN x: ARRAY OF BYTE; beg, len: INTEGER), NEW, ABSTRACT
		END;

		Directory = POINTER TO ABSTRACT RECORD
			(d: Directory) This (IN path: ARRAY OF CHAR): Locator, NEW, ABSTRACT;
			(d: Directory) Temp (): File, NEW, ABSTRACT;
			(d: Directory) New (loc: Locator; ask: BOOLEAN): File, NEW, ABSTRACT;
			(d: Directory) Old (loc: Locator; name: Name; shared: BOOLEAN): File, NEW, ABSTRACT;
			(d: Directory) Delete (loc: Locator; name: Name), NEW, ABSTRACT;
			(d: Directory) Rename (loc: Locator; old, new: Name; ask: BOOLEAN), NEW, ABSTRACT;
			(d: Directory) SameFile (loc0: Locator; name0: Name;
												loc1: Locator; name1: Name): BOOLEAN, NEW, ABSTRACT;
			(d: Directory) FileList (loc: Locator): FileInfo, NEW, ABSTRACT;
			(d: Directory) LocList (loc: Locator): LocInfo, NEW, ABSTRACT;
			(d: Directory) GetFileName (name: Name; type: Type; OUT filename: Name), NEW, ABSTRACT
		END;

	VAR
		dir-, stdDir-: Directory;
		docType-, objType-, symType-: Type;

	PROCEDURE SetDir (d: Directory);

END Files.


Большинству программистов никогда не потребуется работать с файлами напрямую, вместо этого они могут использовать объекты чтения и записи (из модуля -> Stores), которые уже есть в Блэкбоксе!

Модуль FIles предоставляет основные абстракции для работы с иерархическими файловыми системами. Файл  это последовательность байтов. Для одного файла одновременно можно открыть несколько каналов доступа, возможно, на различных позициях.

Файл и его каналы доступа представляются разными структурами данных, называемыми File (файл) и Reader/Writer (объект чтения/объект записи). Для утверждений, справедливых для объектов как чтения, так и записи, будем использовать термин объект доступа или бегунок. Открытый бегунок никогда не закрывается явно, и приложение может создать столько бегунков, сколько нужно.

             старая картинка

Рис. 1: Файл с тремя бегунками


Каждый файл приписан к определенному месту в иерархии файлов (т.е. к папке или поддиректории; в дальнейшем используется слово папка во избежание путаницы с Directory прим. Ф.Т.).
В Блэкбоксе место приписки файла (папка) представляется объектом-локатором (locator). 
Особый фабричныйобъект (directory) предоставляет процедуру, которая создает локатор в соответствии с описанием пути по правилам базовой платформы. Большинство остальных действий с фабричными объектами требуют локатора в качестве параметра, чтобы определить, в какой папке нужно выполнить действие.

Для временных файлов используется особая (явно не задаваемая) системная папка. Временные файлы не могут быть приписаны к какой-либо папке. Модуль Dialog предоставляет дополнительные способы получения локаторов файлов  посредством стандартных диалогов открытия файлов.

Сам файл задается локатором и именем. Имя  это локальное имя для данной папки, то есть оно не может быть описанием пути.

Фабричный объект предоставляет три процедуры для доступа к файлу: New, Temp и Old. 
Процедура New создает новый файл. Этот файл уже принадлежит конкретной папке), но ещё не имеет имени, то есть является анонимным. После записи содержимого файла, он может быть зарегистрирован под нужным именем, возможно, заменяя при этом какой-то уже существующий файл, который в свою очередь становится анонимным. Регистрация файла является атомарной операцией, что уменьшает опасность замены файла новым, но ещё не завершённым или испорченным файлом.

Анонимные файлы, для которых объектов доступа больше нет, автоматически удаляются сборщиком мусора в подходящий момент времени.

Процедура Temp создает временный файл. Такой файл никогда не регистрируется и остается анонимным.

Процедура Old ищет и открывает существующий файл по его имени и месту приписки, представленному локатором. Файл может быть открыт в разделяемом (shared) или монопольном (exclusive) режиме. Разделяемый означает, что файл может быть открыт сразу несколькими программами, но ни одна не может менять его (неизменяемый файл). Даже если файл был открыт, запись о его регистрации в папке, представленной локатором, будет изменена в том случае, когда новый файл регистрируется в той же папке и под тем же именем. В этом случае старый файл остается доступным через существующие бегунки. Однако поиск этого файла процедурой Old даст самую свежую зарегистрированную версию файла. Когда не останется бегунков для старой версии файла, дисковое пространство, занятое ею, будет в конечном счете утилизовано сборщиком мусора.

Открытие файла в разделяемом режиме (shared) является правилом в BlackBox; открытие файла в монопольном режиме (exclusive)  редкое исключение. Монопольно означает, что файл может открыть только одна программа. Пока файл не будет снова закрыт, доступ для других программ будет блокирован, то есть процедура Old для этого файла потерпит неудачу. Монопольно открытый файл может быть изменен (изменяемый файл), что полезно для приложений типа простой базы данных. Регистрация нового файла под тем же именем, что и монопольно открытый файл, даст такой же эффект, что и для разделяемых файлов, то есть существующий файл станет анонимным и будет в конечном счете утилизован сборщиком мусора.

Файл может быть, например, сначала открыт в монопольном режиме, закрыт и затем снова открыт уже в разделяемом режиме. Однако файл нельзя открыть одновременно и в монопольном, и в разделяемом режимах.
Открытые файлы, для которых бегунков больше нет, в подходящий момент автоматически закрываются сборщиком мусора. Рекомендуется явно закрывать файлы, открытые в монопольном режиме, чтобы сделать их доступными для других программ как можно раньше.

Фабричный объект представляет все доступные файлы (а не одну папку), независимо от их мест приписки в иерархии файлов. Существует только одна иерархия файлов. Однако каждая служба Блэкбокса может реализовывать свой собственный фабричный объект. Такой объект представляет в точности ту же самую файловую иерархию, но он может предоставлять альтернативные способы поиска файлов, например, применяя пути поиска по умолчанию, или задавая текущую папку, относительно которой вычисляются имена путей, и т.п.

Файлы типизируются. Это значит, что каждый файл имеет атрибут type, являющийся цепочкой литер, обычно длиной 3 (Windows) или 4 (MacOS) литеры. На некоторых платформах файловая система отдельно помнит типы файлов (MacOS), на других типы файлов эмулируются суффиксами имен файлов  расширениями (Windows). Типы файлов полезны для определения допустимых операций с файлами. Например, в Блэкбоксе можно инсталлировать конвертеры файлов (см. модуль Converters), которые осуществляют преобразования содержимого файла в структуры данных в памяти и обратно.

Пример: ObxAsciidocu


CONST exclusive, shared
Значения, которые могут быть заданы параметру shared процедуры Directory.Old для указания режима, в котором следует открыть файл,  монопольного или разделяемого.

CONST ask, dontAsk
Значения, которые могут передаваться методам Directory.New, Directory.Rename и File.Register.

CONST readOnly
Возможное значение для FileInfo.attr. Показывает, что файл может быть доступен только для чтения.

CONST hidden
Возможное значение для FileInfo.attr. Показывает, что файл не показывается, когда пользователь просматривает (lists) список доступных файлов.

CONST system
Возможное значение для FileInfo.attr. Показывает, что файл является частью операционной системе.

CONST archive
Возможное значение для FileInfo.attr. Показывает, что файл является архивом.

CONST stationery
Возможное значение для FileInfo.attr. Показывает, что файл является шаблоном (stationary).


TYPE Name
Тип цепочек литер для имен файлов.


TYPE Type
Тип цепочек литер для имен типов файлов. Под Windows имена типа файла соответствуют трехсимвольным расширениям имени файла, например, файл XYZ.txt имеет тип txt. Под MacOS используется соответствующее четырехсимвольное имя типа, например файл ASCII xyz имеет тип TEXT.


TYPE Locator
ABSTRACT
Файловый локатор представляет папку в файловой системе.
Локаторы используются в Блэкбоксе и иногда в командах, которые работают с файлами, не принадлежащими Блэкбоксу.
Тип Locator переопределён (extended) в каркасе Блэкбокса.

res: INTEGER
Операции с фабричными объектами возвращают свой результат в поле res локатора.
Предопределены следующие коды для результата:
res = 0	нет ошибки	/	no error
res = 1	неверный параметр (имя или локатор)	/	invalid parameter (name or locator)
res = 2	путь или файл не найден	/	location or file not found
res = 3	файл уже существует	/	file already exists
res = 4	защита от записи	/	write-protection
res = 5	ошибка ввода-вывода	/	io error
res = 6	доступ запрещен	/	access denied
res = 7	неверный тип файла	/	illegal file type
res = 8	отменено	/	cancelled
res = 80	недостаточно памяти	/	not enough memory
res = 81	недостаточно ресурсов (места на диске, описателей файлов и т.д.)	/
	not enough system resources (disk space, file handles, etc.)
Конкретная реализация Блэкбокса может возвращать и другие коды ошибок, специфичные для платформы. Такие коды всегда имеют отрицательные значения.

PROCEDURE (l: Locator) This (IN path: ARRAY OF CHAR): Locator
NEW, ABSTRACT
This вычисляет относительный путь, начиная с положения, соответствующего /.

Постусловие
result # NIL
	l.res = 0	нет ошибки / no error
result = NIL
	l.res = 1	неправильное имя / invalid name
	l.res = 5	ошибка ввода-вывода / io error


TYPE FileInfo
Эта запись представляет информацию о файле.

next: FileInfo
Указатель на следующий элемент списка дескрипторов. Конкретный порядок не определен.

name: Name	name # ""
Имя файла.

length: INTEGER	length >= 0
Длина файла в байтах.

type: Type	type # ""
Тип файла.

modified: RECORD year, month, day, hour, minute, second: INTEGER END
Дата и время последнего изменения файла.

attr: SET
Описывает различные возможные атрибуты файла (readOnly, hidden, system, archive, stationery).


TYPE LocInfo
Эта запись представляет информацию о папке (location).

next: LocInfo
Ссылка на следующий элемент в списке описателей папок. Конретный порядок не определен.

name: Name	name # ""
Имя файла.

attr: SET
Указывает различные возможные атрибуты (readOnly, hidden, system, archive).


TYPE File
ABSTRACT
Файл является носителем (carrier) линейной последовательности байт, которая обычно находится на жестком диске или аналогичном устройстве.
Объекты типа File размещаются в памяти фабричными объектами для файлов.
Объекты типа File используются командами, которые работают с файлами, не принадлежащими Блэкбоксу.
Тип File переопределён (extended) внутри Блэкбокса. 

type-: Type	type # ""
Тип данного файла.

PROCEDURE (f: File) Length (): INTEGER
NEW, ABSTRACT
Возвращает текущую длину файла в байтах.

Постусловие
result >= 0

PROCEDURE (f: File) NewReader (old: Reader): Reader
NEW, ABSTRACT
Возвращает объект чтения подходящего типа (для этого типа фалов). Если old = NIL, то в памяти размещается новый объект. Если old # NIL и old имеет подходящий тип, возвращается old. Возвращенный объект связан с f, его поле eof (от end of file, т.е. конец файла прим. Ф.Т.) установлено в FALSE, и он позиционирован где-то в файле. Если через параметр передан старый объект чтения, то старая позиция будет по-возможности сохранена.
Если передан старый объект чтения, то приложение должно обеспечить, что он нигде больше не используется. Передача неиспользуемого старого объекта позволяет избежать избыточных операций размещения в памяти.

Постусловие
result # NIL
~result.eof
old # NIL & old.Base() = f
	result.Pos() = old.Pos()
old = NIL OR old.Base() # f
	result.Pos() = 0

PROCEDURE (f: File) NewWriter (old: Writer): Writer
NEW, ABSTRACT
Возвращает объект записи подходящего типа (для этого типа фалов) Если old = NIL, то размещается новый записыватель. Если old # NIL и old имеет подходящий тип, возвращается old. Возвращенный объект связан с f и позиционирован где-то в файле. Если в параметре передан старый объект, то старая позиция будет по-возможности сохранена.
Если передан старый объект записи, то приложение должно обеспечить, что он нигде больше не используется. Передача неиспользуемого старого объекта записи позволяет избежать избыточных операций размещения в памяти.
Файлы, доступные только для чтения, не допускают записи. В этом случае NewWriter возвращает NIL.

Постусловие
result # NIL
	old # NIL & old.Base() = f
		result.Pos() = old.Pos()
	old = NIL OR old.Base() # f
		result.Pos() = f.Length()
result = NIL
	файл доступен только для чтения

PROCEDURE (f: File) Flush
NEW, ABSTRACT
Чтобы гарантировать согласованность файла, следует вызвать Flush после последней операции записи. Избыточные вызовы Flush не имеют эффекта.
Реализация Close может вызывать Flush.
 

PROCEDURE (f: File) Register (name: Name; type: Type; ask: BOOLEAN; OUT res: INTEGER)
NEW, ABSTRACT
Процедура Register гарантирует, что  анонимный до сих пор файл будет доступен в будущем. Если файл с тем же именем и в той же папке уже существует, старая версия сначала удаляется. Если удалить его не удаётся, например, когда файл защищен от записи, то по значению ask определяется, нужно ли показать системное (зависящее от платформы) сообщение об ошибке. В качестве значений здесь можно передавать константы ask или dontAsk.
Процедуру Register можно рассматривать как атомарное действие.
Можно регистрировать только файлы, открытые процедурой New. Попытка зарегистрировать файл, открытый посредством Old, вызовет ошибку нарушения предусловия.
Если при вызове Register удаляется уже существующий файл, то стирается только запись о нём в файловой системе. Содержимое файла все еще доступно через существующие объекты доступа. Когда таковых для него больше не останется, пространство, занятое файлом, будет через неопределённое время утилизовано.
Файл f и его объекты доступа становятся неопределёнными после регистрации f, то есть никакие операции с ними больше не возможны. Это также означает, что Register можно выполнить только однажды. Однако, зарегистрированный файл можно вновь открыть процедурой Old.
Register может вызвать Flush и закрывает файл.
Каждый зарегистрированный файл имеет тип, который передается процедуре Register в параметре type.

Предусловие
f анонимный и не временный	20
name # ""	21
name является именем файла	22

Постусловие
res = 0	нет ошибки	/	no error
res = 1	неверный параметр (имя или локатор)	/	invalid parameter (name or locator)
res = 2	папка или файл не найден	/	location or file not found
res = 3	файл уже существует	/	file already exists
res = 4	защита от записи	/	write-protection
res = 5	ошибка ввода-вывода	/	io error
res = 6	доступ запрещен	/	access denied
res = 7	неправильный тип файла	/	illegal file type
res = 8	отменено	/	cancelled
res = 80	недостаточно памяти	/	not enough memory
res = 81	недостаточно ресурсов (места на диске, описателей файлов и т.д.)	/
	not enough system resources (disk space, file handles, etc.)
Конкретная реализация Блэкбокса может возвращать и другие коды ошибок, специфичные для платформы. Такие коды всегда имеют отрицательные значения.

PROCEDURE (f: File) Close
NEW, ABSTRACT
Закрывает открытый файл. Close не делает ничего, если файл не был открыт или если он открыт в разделяемом режиме. Если вызов New или Old не был сбалансирован вызовом Close, закрытие произойдет автоматически через неопределенное время. Если известно, что файл больше не понадобится, рекомендуется вызывать процедуру Close.
Файл f и его объекты доступа становятся неопределены после закрытия f, то есть никакие операции с ними больше невозможны. Однако закрытый файл можно открыть позднее процедурой Old.
Close может вызывать Flush.
Close полезно (но не обязательно) вызывать сразу после того, как файл стал ненужным.

PROCEDURE (f: File) InitType (type: Type)
Инициализирует поле type файла.

Предусловие
type # ""	20
f.type = "" OR f.type = type	21


TYPE Reader
ABSTRACT
Объект, предоставляющий средства чтения содержимого файла.
Объекты чтения размещаются в памяти конкретными объектами типа File.
Используются командами, которые читают файлы, не принадлежащие Блэкбоксу, и работают с ними на уровне байт.
Тип Reader переопределён (extended) в каркасе Блэкбокса.

eof: BOOLEAN
Выставляется (в TRUE) при попытке чтения байта после конца файла (ReadByte или ReadBytes). Сбрасывается (в FALSE), когда объект чтения создается или позиционируется.

PROCEDURE (r: Reader) Base (): File
NEW, ABSTRACT
Возвращает файл, к которому объект чтения подключён в данный момент.

Постусловие
result # NIL

PROCEDURE (r: Reader) Pos (): INTEGER
NEW, ABSTRACT
Возвращает текущую позицию объекта чтения.

Постусловие
0 <= result <= r.Base().Length()

PROCEDURE (r: Reader) SetPos (pos: INTEGER)
NEW, ABSTRACT
Устанавливает объект чтения в позицию pos, делая её текущей, и сбрасывает флаг eof.

Предусловие
pos >= 0	20
pos <= r.Base().Length()	21

Постусловие
r.Pos() = pos
~r.eof

PROCEDURE (r: Reader) ReadByte (OUT x: BYTE)
NEW, ABSTRACT
Пытается прочесть следующий байт за текущей позицией. В случае успеха увеличивает позицию на единицу. Если текущая позиция (до чтения) является концом доступных данных, то есть Pos равно длине данных носителя, то выставляется r.eof.
ReadByte вызывает SetPos.

Постусловие
r.Pos()' < r.Base().Length()
	r.Pos() = r.Pos()' + 1
	~r.eof
	x = байт после r.Pos()'
r.Pos()' = r.Base().Length()
	r.Pos() = r.Base().Length()
	r.eof
	x = 0H

PROCEDURE (r: Reader) ReadBytes (VAR x: ARRAY OF BYTE; beg, len: INTEGER)
NEW, ABSTRACT
Пытается прочессть len байт, следующих за текущей позицией. Увеличивает позицию на число успешно прочитанных байт. Если имеет место попытка читать за концом файла, то выставляется r.eof. Данные записываются в массив x, начиная с элемента с индексом beg.
ReadBytes вызывает SetPos.

Предусловие
beg >= 0	20
len >= 0	21
beg + len <= LEN(x)	22

Постусловие
r.Pos()' <= r.Base().Length() - len
	r.Pos() = r.Pos()' + len
	~r.eof
	len байт читаются после r.Pos()' и записыватся в x
r.Pos()' > r.Base().Length() - len
	r.Pos() = r.Base().Length()
	r.eof
	r.Base().Length() - r.Pos()' байт читаются после r.Pos()' и считываются в x


TYPE Writer
ABSTRACT
Объект, обеспечивающий доступ к содержимому файла для записи.
Объекты записи размещаются в памяти конкретными объектами типа File.
Используются командами, которые записывают файлы, не принадлежащие Блэкбоксу, и работают с ними на уровне байт.
Тип Writer переопределён (extended) внутри Блэкбокса.

PROCEDURE (w: Writer) Base (): File
NEW, ABSTRACT
Возвращает файл, к которому объект записи подключён в данный момент.

Постусловие
result # NIL

PROCEDURE (w: Writer) Pos (): INTEGER
NEW, ABSTRACT
Возвращает текущую позицию объекта записи.

Постусловие
0 <= result <= w.Base().Length()

PROCEDURE (w: Writer) SetPos (pos: INTEGER)
NEW, ABSTRACT
Устанавливает объект записи в позицию pos, делая её текущей

Предусловие
pos >= 0	20
pos <= w.Base().Length()	21

Постусловие
w.Pos() = pos

PROCEDURE (w: Writer) WriteByte (x: BYTE)
NEW, ABSTRACT
Записывает байт после текущей позиции, затем увеличивает позицию на единицу. Если текущая позиция является концом данных носителя, то его длина также увеличивается.
WriteByte вызывает SetPos.

Постусловие
x written at w.Pos()'
w.Pos() = w.Pos()' + 1
w.Pos()' < w.Base().Length()'
	w.Base().Length() = w.Base().Length()'
	значение x переписало старое значение после w.Pos()'
w.Pos()' = w.Base().Length()'
	w.Base().Length() = w.Base().Length()' + 1
	значение x было приписано в конце

PROCEDURE (w: Writer) WriteBytes (IN x: ARRAY OF BYTE; beg, len: INTEGER)
NEW, ABSTRACT
Записывает len байт после текущей позиции и увеличивает позицию соответственно. Если нужно, длина носителя тоже увеличивается. Данные передаются из массива x, начиная с элемента beg.
WriteBytes вызывает SetPos.

Предусловие
beg >= 0	20
len >= 0	21
beg + len <= LEN(x)	22

Постусловие
len байт передаются из переменной x в носитель
w.Pos() = w.Pos()' + len
w.Pos()' + len <= w.Base().Length()'
	w.Base().Length() = w.Base().Length()'
w.Pos()' + len > w.Base().Length()'
	w.Base().Length() = w.Pos()' + len


TYPE Directory
ABSTRACT
Фабричный объект для поиска файлов и других операций в файловых системах.
Фабричные объекты размещаются в памяти Блэкбоксом.
Используются командами, которые работают с файлами, не принадлежащими Блэкбоксу.
Тип Directory переопределён внутри модуля.

PROCEDURE (d: Directory) This (IN path: ARRAY OF CHAR): Locator
NEW, ABSTRACT
Возвращает локатор, соответствующий описанию пути path, которое должно следовать соглашениям базовой платформы.
This может выполнять некоторые проверки корректности, например, проверку правильности синтаксиса параметра path. Передача пустой цепочки литер создает локатор по умолчанию (обычно соответствует папке самого Блэкбокса).

Постусловие
result # NIL
result.res = 0
	допустимый локатор
result.res # 0
	недопустимый локатор

PROCEDURE (d: Directory) Temp (): File
NEW, ABSTRACT
Возвращает временный файл. Этот файл анонимный, то есть не зарегистрирован ни в какой папке. (В некоторых файловых системах анонимные файлы непосредственно не поддерживаются, они могут присутствовать под временными именами в подходящей папке). Регистрация временного файла невозможна.
Временный файл всегда допускает чтение и запись (изменяемый файл).

Постусловие
result # NIL

PROCEDURE (d: Directory) New (loc: Locator; ask: BOOLEAN): File
NEW, ABSTRACT
Возвращает новый файловый объект (или NIL, если это невозможно). Этот файл анонимный, то есть не зарегистрирован в папке, соответствующей локатору loc. (В некоторых файловых системах анонимные файлы непосредственно не поддерживаются, они могут присутствовать под временными именами в папке loc.) Если файл позднее регистрируется, он появляется в папке, соответствующей локатору loc.
Если loc указывает папку, которой ещё нет, она сначала будет создана. Параметр ask определяет, нужно ли запрашивать на это подтверждение у пользователя. Можно подставлять константы ask или dontAsk.
Новый файл всегда допускает чтение и запись (изменяемый файл).
Если папка loc не существует, у пользователя может быть запрошено подтверждение, следует ли создать папку (loc.res = 0) или нет (loc.res = 8).

Предусловие
loc # NIL	20

Постусловие
result # NIL
	loc.res = 0	ошибок нет / no error
result = NIL
	loc.res = 1	неправильное имя / invalid name
	loc.res = 2	папка не найдена / location not found
	loc.res = 4	защита от записи / write-protection
	loc.res = 5	ошибка ввода-вывода / io error
	loc.res = 8	произошла отмена / cancelled

PROCEDURE (d: Directory) Old (loc: Locator; name: Name; shared: BOOLEAN): File
NEW, ABSTRACT
Ищет и открывает файл с именем name в папке, соответствующей локатору loc. Возвращается этот файл (или NIL, если это невозможно). Параметр shared определяет, возвращается ли файл в разделяемом или монопольном режиме. Разделяемый файл допускает только чтение. Это значит, что несколько приложений могут одновременно читать файл, но его нельзя изменять. Монопольно открытый файл предоставляет исключительный доступ для чтения и записи. Это значит, что доступ для чтения или записи будет закрыт любому другому приложению. Однако приложение может передать указатель на файл туда, куда захочет. Суть в том, что другое приложение не может получить доступ к этому файлу только через фабричный объект, без кооперации с приложением, владеющим доступом к файлу в настоящий момент. Кроме того, монопольный доступ не запрещает иметь для файла несколько активных объектов доступа.
Файл обычно открывается в разделяемом режиме. Для изменения содержимого существующего файла создается новый файл и затем регистрируется под старым именем. Монопольный режим может оказаться предпочтительным, когда в реальности изменяется только небольшая часть данных, например, при реализации простых баз данных. В этом случае следует закрыть файл сразу, как только он станет больше не нужен.

Предусловие
loc # NIL	20
name # ""	21

Постусловие
result # NIL
	loc.res = 0	нет ошибок / no error
result = NIL
	loc.res = 1	неправильное имя / invalid name
	loc.res = 2	папка или файл не найден / location or file not found
	loc.res = 6	доступ запрещён / access denied

PROCEDURE (d: Directory) Delete (loc: Locator; name: Name)
NEW, ABSTRACT
Удаляет файл, заданный loc и name.

Предусловие
loc # NIL	20

Постусловие
loc.res = 0	нет ошибок / no error
loc.res = 1	неправильные параметр (имя или локатор) / invalid parameter (name or locator)
loc.res = 2	папка или файл не найден / location or file not found
loc.res = 4	защита от записи / write-protection
loc.res = 5	ошибка ввода-вывода / io error

PROCEDURE (d: Directory) Rename (loc: Locator; old, new: Name; ask: BOOLEAN)
NEW, ABSTRACT
Переименовывает файл, заданный loc и old, давая ему локальное имя new. Если файл с именем new уже существует, его следует сначала удалить. Параметр ask задает, нужно ли спрашивать у пользователя разрешения на это. Здесь можно подставлять константу ask или dontAsk.

Предусловие
loc # NIL	20

Постусловие
loc.res = 0	нет ошибок / no error
loc.res = 1	неправильный параметр (локатор или имя) / invalid parameter (locator or name)
loc.res = 2	папка или файл не найден / location or file not found
loc.res = 3	файл уже существует / file already exists
loc.res = 4	защита от записи / write-protection
loc.res = 5	ошибка ввода-вывода / io error

PROCEDURE (d: Directory) SameFile (loc0: Locator; name0: Name;
															loc1: Locator; name1: Name): BOOLEAN;
NEW, ABSTRACT
Определяет, когда две пары (локатор, имя) задают один и тот же файл.

Предусловие
loc0 # NIL	20
name0 # ""	21
loc1 # NIL	22
name1 # ""	23

PROCEDURE (d: Directory) FileList (loc: Locator): FileInfo
NEW, ABSTRACT
Возвращает информацию о файлах в папке, соответствующей локатору. Результат  линейный список описателей файлов, без определенного порядка. Процедура может изменять loc.res.

Предусловие
loc # NIL	20

PROCEDURE (d: Directory) LocList (loc: Locator): LocInfo
NEW, ABSTRACT
Возвращает информацию о подпапках папки, соответствующей локатору. Результат  линейный список дескрипторов подпапок, без определенного порядка. Процедура может изменять loc.res.

Предусловие
loc # NIL	20

PROCEDURE (d: Directory) GetFileName (name: Name; type: Type; OUT filename: Name)
NEW, ABSTRACT
Составляет имя файла из файла и его типа.
Windows: filename = name + "." + type
Mac OS: filename = name


VAR dir-, stdDir-: Directory	(dir # NIL) & (stdDir # NIL)
Фабричные объект для работы с файлами.

PROCEDURE SetDir (d: Directory)
Установить фабричный объект.
SetDir используется при конфигурации.

Предусловие
d # NIL	20

Постусловие
stdDir' = NIL
	stdDir = d
stdDir' # NIL
	stdDir = stdDir'
dir = d

VAR docType-, objType-, symType-: Type	(docType # NIL) & (objType # NIL) & (symType # NIL)
Типы файлов документов, кодовых файлов и символьных файлов Блэкбокса.