// Определяет кодировку, если обработчику события "data" данные должны
// передаваться в виде строк
s.setEncoding(enc); // Как декодировать байты: "utf8”, "ascii" или "base64"
Потоки, открытые для записи, не так тесно связаны с событиями, как потоки, открытые
для чтения. Метод
write
таких потоков используется для отправки данных, а метод
end
– для закрытия потока, когда все данные будут записаны. Метод
write
никогда не блокируется. Если интерпретатор Node окажется не в состоянии записать данные немедленно и во внутреннем буфере потока не окажется сводного места, метод
write
вернет
false
. Чтобы узнать, когда интерпретатор вытолкнет буфер и данные фактически будут записаны, можно зарегистрировать обработчик события «drain»:
// Выходной поток s:
s.write(buffer); // Запись двоичных данных
s.write(string, encoding) // Запись строковых данных.
// по умолчанию encoding = "utf-8"
s.end // Закроет поток.
s.end(buffer); // Запишет последнюю порцию данных и закроет поток.
s.end(str, encoding) // Запишет последнюю строку и закроет поток
s.writeable; // true, если поток по-прежнему открыт для записи
s.on("drain", f) // f будет вызываться при опустошении внутр. буфера
Как видно из примеров выше, потоки ввода/вывода, реализованные в интерпретаторе Node, могут работать и с двоичными, и с текстовыми данными. Текст передается с использованием простых строк JavaScript. Байты обрабатываются с помощью специфического для Node типа данных
Buffer
. Буферы в интерпретаторе Node являются объектами, подобными массивам, с фиксированной длиной, элементами которых могут быть только числа в диапазоне от 0 до 255. Программы, выполняющиеся под управлением Node, часто интерпретируют буферы как непрозрачные блоки данных, читая их из одного потока и записывая в другой. Тем не менее байты в буфере доступны как обычные элементы массива, а сами буферы имеют методы, позволяющие копировать байты из одного буфера в другой, получать срезы буфера, записывать строки в буфер с использованием заданной кодировки и декодировать буфер или его часть обратно в строку:
var bytes = new Buffer(256); //Создать новый буфер на 256 байт
for (var i = 0; i < bytes.length; i++) //Цикл по индексам
bytes[i]=i //Установить каждый элемент в буфере
var end = bytes.slice(240,256) //Получить срез буфера
end[0] //=> 240: end[0] = bytes[240]
end[0]=0 //Изменить элемент среза
bytes[240] //=> 0; буфер тоже изменится
var more=new Buffer(8); //Создать новый отдельный буфер
end.copy(more, 0, 8, 16) //Скопировать элементы 8-15 из end[] в more[]
more[0] //=> 248
//
Буферы также позволяют выполнять преобразования двоичных данных в строки
// и обратно. Допустимые кодировки: "utf8", "ascii" и "base64".
// По умолчанию используется "utf8".
var buf = new Buffer("2пr", "utf8”); // Закодировать текст в байты, UTF-8
buf.length // => 3 символа занимают 4 байта
buf.toSt ring // => "2яг": обратно в текст
buf = new Buffer(10); // Новый буфер фиксированной длины
var len = buf.write("пr2", 4); // Записать текст, начиная с 4-го байта
Инструменты интерпретатора Node для работы с файлами и файловой системой находятся в модуле «fs»:
var fs = require("fs"); // Загрузит инструменты для работы с файловой системой
Для большинства своих методов этот модуль предоставляет синхронные версии. Любой метод, имя которого оканчивается на «Sync», является блокирующим методом, возвращающим значение и возбуждающим исключение. Методы для работы с файловой системой, имена которых не оканчиваются на «Sync», являются неблокирующими - они возвращают результаты или ошибки посредством передаваемых им функций обратного вызова. Следующий фрагмент демонстрирует, как реализуется чтение текстового файла с использованием блокирующего метода и как реализуется чтение двоичного файла с использованием неблокирующего метода:
// Синхронное чтение файла. Следует передать имя кодировки,
// чтобы в результате получить текст, а не двоичные байты,
var text = fs.readFileSync("config.json", "utf8");
// Асинхронное чтение двоичного файла. Следует передать функцию, чтобы получить данные
fs.readFile("image.png", function(err, buffer) {
if (err) throw err; // Если что-то пошло не так
process(buffer); // Содержимое файла в параметре buffer
Функции, представленные выше, интерпретируют содержимое файла как единственную строку или объект
Buffer
. Кроме того, для чтения и записи файлов интерпретатор Node определяет также API потоков ввода/вывода. Функция ниже копирует содержимое одного файла в другой:
// Копирование файлов с применением API потоков ввода/вывода.