Давайте теперь рассмотрим асинхронную работу
с файловой системой. Как правило, в NodeJS
все методы модуля fs
существуют в
двух вариантах: в синхронном и асинхронном.
Например, для синхронного чтения файла используется
метод readFileSync
, а для асинхронного
- readFile
. Аналогично для записи
файла существует пара writeFileSync
и writeFile
.
Асинхронное чтение файла
Метод readFile
первым параметром принимает
имя или путь к файлу, вторым параметром -
кодировку, а третьим - коллбэк, который выполнится
после чтения файла.
В коллбэк следует передавать два параметра. В первый параметр попадет объект с ошибкой, если она произойдет, а во второй - текст прочитанного файла.
Давайте для примера прочитаем текст какого-нибудь файла:
fs.readFile('readme.txt', 'utf8', function(err, data) {
console.log(data);
});
Дан файл с числом. Прочитайте этот файл и выведите в консоль квадрат этого числа.
Проверка асинхронности
Можно убедится в том, что чтение файла происходит
асинхронно. Для этого выведем что-нибудь
в консоль после работы с методом readFile
:
fs.readFile('readme.txt', 'utf8', function(err, data) {
console.log(data);
});
console.log('!!!');
Как вы уже знаете, коллбэк выполнится, когда
файл будет прочитан. А пока файл читается,
код скрипта будет выполнятся дальше. Это
значит, что в консоли сначала появится результат
второго console.log
, а потом первого.
Проверьте, что код после метода readFile
будет выполнен раньше, чем будет прочитан файл.
Обработка исключительных ситуаций
Так как наш код асинхронный, то исключительные
ситуации нельзя поймать через try-catch
.
Для обработки исключений в коллбэке предназначен
первый параметр. Этот параметр будет содержать
null
, если исключения не случилось,
или объект с ошибкой, если исключение произошло.
Давайте допишем код коллбэка так, чтобы он обрабатывал исключительные ситуации:
fs.readFile('readme.txt', 'utf8', function(err, data) {
if (!err) {
console.log(data);
} else {
console.log('ошибка', err);
}
});
Попробуйте прочитать несуществующий файл. Убедитесь, что при этом произойдет исключительная ситуация. Допишите ваш код так, чтобы он обрабатывал эту ситуацию.
Асинхронная запись файла
Асинхронная запись текста в файл выполняется аналогично:
fs.writeFile('readme.txt', 'text', function(err) {
if (err) {
console.log('ошибка');
}
});
С помощью цикла создайте 10
файлов,
содержащих целые числа от 1
до 10
.
Асинхронное чтение нескольких файлов
Пусть у нас есть два файла с числами. Давайте найдем произведение этих чисел. Очевидно, что для этого нам нужно прочитать оба этих файла.
Но, так как код асинхронный, нам нужно читать второй файл в коллбэке первого:
fs.readFile('readme1.txt', 'utf8', function(err, data1) {
if (!err) {
fs.readFile('readme2.txt', 'utf8', function(err, data2) {
if (!err) {
console.log(data1 * data2);
} else {
console.log('ошибка чтения файла readme2');
}
});
} else {
console.log('ошибка чтения файла readme1');
}
});
Даны три файла с числами. Выведите в консоль сумму этих чисел.
Даны пять файлов с числами. Выведите в консоль сумму этих чисел.
Асинхронное чтение и запись файла
Предположим нам нужно прочитать файл, сделать его текстом операцию и записать обратно в этот или другой файл. В этом случае запись в файл нужно будет делать в коллбэке чтения:
fs.readFile('readme.txt', 'utf8', function(err, data) {
if (!err) {
fs.writeFile('readme.txt', data + '!', function(err) {
if (err) {
console.log('ошибка записи файла');
}
});
} else {
console.log('ошибка чтения файла');
}
});
Дан файл с числом. Запишите в этот файл квадрат этого числа.
Даны три файла с числами. Запишите в новый файл сумму этих чисел.
Стрелочные функции
Как правило коллбэки в NodeJS делают с помощью стрелочных функций. Это сокращает код, но несколько затрудняет понимание с непривычки.
Давайте переделаем предыдущий код на стрелочные функции:
fs.readFile('readme.txt', 'utf8', (err, data) => {
if (!err) {
fs.writeFile('readme.txt', data + '!', err => {
if (err) {
console.log('ошибка записи файла');
}
});
} else {
console.log('ошибка чтения файла');
}
});
Дан код:
fs.readFile('readme1.txt', 'utf8', function(err, data1) {
if (!err) {
fs.readFile('readme2.txt', 'utf8', function(err, data2) {
if (!err) {
fs.writeFile('readme.txt', data1 + data2, function(err) {
if (err) {
console.log('ошибка записи файла');
}
});
} else {
console.log('ошибка чтения файла readme2');
}
});
} else {
console.log('ошибка чтения файла readme1');
}
});
Перепишите его через стрелочные функции.