rebol document

Глава 14 - Порты

Руководство пользователя REBOL/Core
Основное содержание
Отправьте нам отзыв

Содержание:

1. Обзор
2. Открытие порта
2.1 Функция открытия
2.2 Открытые уточнения
3. Закрытие порта
4. Чтение из порта
5. Запись в порт
6. Обновление порта
7. Ожидание порта
8. Другие режимы порта
8.1 Линейный режим
8.2 Только чтение и запись
8.3 Прямой доступ к портам
8.4 Пропуск данных
9. Права доступа к файлам
10. Порты каталогов

1. Обзор

Порты обращаются к внешним (external) сериям, таким как файлы, сети, консоли, события, базы данных, кодировщики данных и декодеры данных. Данные порта обрабатываются с использованием стандартных функций серии REBOL, как описано в главе «Серии».

Порты используются как для ввода, так и для вывода. Тип данных, которые обрабатывает порт, зависит от того, как порт открыт. Возможны три типа данных:

 Stringсерия байтов, преобразует разрывы строк (по умолчанию)
 Binaryсерия байтов, без преобразования данных
 Blockсерия значений REBOL

Порт можно открыть в одном из двух режимов буферизации:

 Bufferedвсе данные хранятся в памяти (по умолчанию)
 Directданные не хранятся в памяти

Кроме того, порт можно открыть с помощью:

 Waitпорт будет ждать данных (по умолчанию)
 No-waitпорт не будет ждать данных

2. Открытие порта

2.1 Функция открытия

Функция open инициализирует доступ к порту в соответствии с указанными параметрами. Функция может быть снабжена именем файла, URL-адресом или объектом. Кроме того, есть несколько уточнений, которые повлияют на операцию открытия или доступ к данным порта.

Самый простой способ использования open - предоставить ему имя файла или URL в качестве аргумента. В приведенном ниже примере открывается файловый порт:

fp: open %file.txt

FP переменная относится к порту. Если порт не открылся, произойдет ошибка. При необходимости ошибку можно отловить с помощью функции try.

По умолчанию файл открывается как буферизованный. Это означает, что к файлу осуществляется доступ и модифицируется в памяти, и изменения в файл не записываются, пока порт не будет закрыт или обновлен.

Для файлов функция open автоматически создаст файл, если он еще не существует.

close open %somefile.txt
if exists? %somefile.txt [print "somefile exists"]
somefile exists

Уточнение /new может быть использовано для перезаписи существующего файла.

write %somefile.txt "text in some file"
print read %somefile.txt
text in some file
close insert open/new %somefile.txt "new data"
print read %somefile.txt
new data

После того, как порт открыт, последовательные операции, такие как копирование (copy), вставка (insert), удаление (remove), очистка (clear), первый (first), следующий (next) и длина? (length?) может использоваться для доступа и изменения содержимого порта.

2.2 Уточнения функции open

Функция open принимает ряд уточнений, которые можно использовать для изменения ее работы:

 /binaryданные порта являются двоичными
 /stringданные порта - текст, перевод всех символов окончаний строк
 /withуказать альтернативное завершение строки
 /linesобрабатывать данные построчно или как блок строк
 /directне буферизировать порт
 /new создать или воссоздать цель порта
 /readоткрыт для операции только для чтения
 /writeоткрыт только для записи
 /no-waitне ждать данных
 /skipпропустить часть данных
 /allowуказать атрибуты защиты файлов
 /customразрешить особые уточнения

3. Закрытие порта

Доступ к порту завершается функцией close (закрыть). Все несохраненные буферизованные данные будут записаны в целевой файл. В приведенном ниже примере будет закрыт порт, открытый ранее:

close fp

Если вы попытаетесь закрыть закрытый порт, произойдет ошибка.

Закрытый порт можно снова открыть с помощью функции open:

open fp

4. Чтение из порта

Функция copy используется для чтения данных из открытого порта:

print copy fp
I wanted the gold, and I sought it,I scrabbled and mucked like
a slave....

Эта функция будет ждать данных порта. Если вы не хотите ждать данных, откройте порт с уточнением /no-wait.

Чтобы прочитать только часть данных порта, используйте copy/part:

print copy/part fp 35
I wanted the gold, and I sought it,

Обратите внимание, что вторым аргументом для копирования может быть длина или позиция в порту.

Вы можете использовать функции поиска (find) и копирования (copy) серий, чтобы прочитать только часть данных порта:

a: find fp "famine"
print copy/part a find a newline
famine or scurvy -- I fought it;

В порте также могут использоваться функции first, next и другие позиционные последовательные функции:

print first fp
I
print first next next fp
w

Функция copy не вернет none, когда все данные будут прочитаны из порта. Когда не работает в /no-wait режима, то функция copy возвращает пустую строку, если нет данных для порта.

tp: open/direct/binary/no-wait tcp://system:8000
content: make binary! 1000
while [wait tp  data: copy tp] [append content data]
close tp

5. Запись в порт

Функция вставки (insert ) используется для записи в порт.

insert fp "I was a fool to seek it."

Если порт находится в буфере, изменение будет происходить извне, когда порт будет закрыт или обновлен (с функцией update). Если порт открыт с помощью /direct, изменение произойдет немедленно.

Все уточнения функции insert могут быть использованы для порта. Например, чтобы записать в порт 20 пробелов:

insert/dup fp " " 20

Вы также можете использовать для порта функции remove (удаления), clear (очистки), change (изменения), append (добавления), replace (замены) и другие функции изменения серии.

Например, чтобы удалить один символ или несколько символов:

remove fp

remove/part fp 20

и чтобы удалить все оставшиеся символы, напишите:

clear fp

6. Обновление порта

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

update fp

7. Ожидание порта

Функция wait (ожидание) важна для программ, которым необходимо обрабатывать асинхронную передачу данных. С помощью wait вы можете дождаться данных на одном или нескольких портах или истечения времени ожидания.

Функция wait принимает один порт:

wait port

или может быть предоставлен целый блок портов:

wait [port1 port2 port3]

Кроме того, значение тайм-аута может быть указано в секундах или в виде значения времени:

wait [port1 port2 10]

wait [port1 port2 0:00:05]

В первом примере время ожидания истекает через десять секунд. Во втором примере тайм-аут будет через пять секунд.

Функция wait вернет порт, который готов или none, если истекло время ожидания.

ready: wait [port1 port2 10]
if ready [data: copy ready]

В приведенном выше примере данные будут считываться из первого готового порта, если тайм-аут не наступил.

Чтобы получить блок всех готовых портов, используйте уточнение /all.

ready: wait/all [port1 port2 10]
if ready [
    foreach port ready [
        append data copy port
    ]
]

В этом примере данные со всех готовых портов будут добавлены в одну серию.

Вы также можете использовать функцию отправки (dispatch) для оценки блока или функции на основе результатов ожидания (wait) на нескольких портах.

dispatch [
    port1 [print "port1 awake"]
    port2 [print "port2 awake"]
    10 [print "timeout!"]
]

Используйте /No-wait и /Direct

Чтобы использовать wait с большинством портов, вам нужно будет указать уточнения / no-wait и / direct как часть open. Это указывает на то, что обычные функции доступа к данным не должны блокироваться и что данные не буферизуются.

port1: open/no-wait/direct tcp://system:8000

8. Другие режимы порта

8.1 Линейный режим

Функция open позволяет открывать порты для линейного доступа. В строчном режиме первая функция вернет строку текста, а не символ. В приведенном ниже примере файл читается по одной строке за раз:

fp: open/lines %file.txt
print first fp
I wanted the gold, and I got it --
print third fp
Yet somehow life's not what I thought it,

Уточнение /lines также полезно для интернет-протоколов, ориентированных на линию (строк).

tp: open/lines tcp://server:8000
print first tp

8.2 Только чтение и запись

Вы можете использовать уточнение /read, чтобы открыть порт только для чтения:

fp: open/read %file.txt

Изменения, внесенные в буфер порта, не записываются обратно в файл.

Чтобы открыть только для записи, используйте уточнение /write:

fp: open/write %file.txt

Файловые порты, открытые с уточнением /write, не будут читать текущие данные при открытии порта.

Закрытие или обновление файлового порта только для записи приведет к перезаписи существующих данных в файле:

insert fp "This is the law of the Yukon..."
close fp
print read %file.txt
This is the law of the Yukon...

8.3 Прямой доступ к порту

Уточнение /direct открывает небуферизованный порт. Это полезно для доступа к файлам по частям, например, когда файл слишком велик для хранения в памяти.

fp: open/direct %file.txt

Чтение данных с помощью функции copy переместит голову указателя порта вперед:

print copy/part fp 40
I wanted the gold, and I sought it,^/ I
print copy/part fp 40
scrabbled and mucked like a slave.^/Was i

В прямом режиме указатель порт всегда будет в исходном положении:

print head? fp
true

Функция copy вернет none, когда порт достигнет своего конца.

Вот пример, который использует прямые порты для копирования файла любого размера:

from-port: open/direct %a-file.jpg
to-port: open/direct %a-file.jpg
while [data: copy/part from-port 100000 ][
    append to-port data
]
close from-port
close to-port

8.4 Пропуск данных

Есть два способа пропустить данные, существующие в порту. Во-первых, вы можете открыть порт с уточнением /skip. Эта функция open автоматически перейдет к определенной точке порта. Например:

fp: open/direct/skip %file.big 1000000

fp: open/skip http://www.example.com/bigfile.dat 100000

Вы также можете использовать функцию skip порта. Для файлов, которые открываются с помощью /direct и /binary, операция пропуска идентична операции поиска в файловой системе. Данные не считываются в память. Это невозможно в режиме /string, потому что разрывы строк влияют на размер пропуска.

fp: open/direct/binary %file.dat
fp: skip fp 100000

9. Права доступа к файлам

Когда файлы создаются REBOL, устанавливаются права доступа по умолчанию. В системах Windows и Macintosh файлы создаются с правами полного доступа. В системах UNIX файлы создаются с разрешениями, установленными на текущую настройку umask.

При использовании open или write для доступа к файлу уточнение /allow используется для установки разрешений на доступ к файлу.

Уточнение /allow принимает блок в качестве аргумента. Этот блок может состоять из любого или всех трех слов read, write и execute.

Ограничения операционной системы

Уточнение /allow только установить разрешения на операционных системах , поддерживающих заданную настройку разрешений. Если операционная система не поддерживает используемый параметр разрешений, он будет проигнорирован. Например, файлы в системах UNIX могут быть установлены как исполняемые (execute), но операционные системы Windows и Macintosh не поддерживают это. При работе с системами UNIX разрешения, установленные с помощью /allow, будут устанавливать только права пользователя. Использование /allow приведет к удалению всех прав доступа для пользователей и других лиц.

Чтобы сделать файл доступным только для чтения, используйте open/allow или write/allow с блоком чтения.

write/allow %file.txt [read]

Чтобы сделать файл читаемым и исполняемым:

open/allow %file.txt [read execute]

Вы можете установить аналогичные разрешения для доступа на запись:

write/allow %file.txt [read write]

Чтобы предотвратить любой доступ к файлу (для операционных систем, где это имело бы значение), предоставьте пустой блок разрешений:

write/allow %file.txt []

Чтобы разрешить полный доступ:

write/allow %file [read write execute]

10. Порты каталогов

Порты каталогов позволяют открывать прямой доступ к каталогам файлов. В системе именно так создается большинство других функций каталогов.

Когда вы открываете каталог, вы получаете прямой доступ к нему в виде блока имен файлов:

mydir: open %intro/
forall mydir [print first mydir]
CVS/
history.t
intro.t
overview.t
quick.t
close mydir

Вы можете перейти к определенной позиции в серии каталогов и удалить файл с таким кодом, как:

dir: open %.
remove next dir
close dir

Это удаляет второй файл в текущем каталоге. По аналогии,

remove at dir 5

удалит пятый файл в каталоге и:

clear dir

удалит все файлы в каталоге.

Чтобы удалить все файлы, содержащие слово "junk", вы можете написать:

dir: open %intro/
while [not tail? dir] [
    either find first dir "junk" [remove dir][
        dir: next dir
    ]
]
close dir

Изменения, внесенные в каталог, производятся при закрытии каталога или при его обновлении. Чтобы действие было выполнено немедленно, используйте такую ​​строку, как:

update dir

Метод доступа к каталогам также может использоваться для изменения имен файлов. После open строка:

change at dir 3 %newname.txt

переименует третий файл в каталоге. Аналогичным образом можно изменить имена любого из файлов в каталоге.

Вот пример, который переименовывает все файлы в каталоге, добавляя слово REBOL к их именам:

dir: open %intro/
forall dir [insert first dir "REBOL"]
close dir

Updated 8-Apr-2005 - Copyright REBOL Technologies - Formatted with MakeDoc2
REBOL.com Documents Manual Dictionary Library Feedback