Как найти файл javascript

Сегодня, в девятой части перевода руководства по Node.js, мы поговорим о работе с файлами. В частности, речь пойдёт о модулях fs и path — о файловых дескрипторах, о путях к файлам, о получении информации о файлах, об их чтении и записи, о работе с директориями.

[Советуем почитать] Другие части цикла

Часть 1: Общие сведения и начало работы
Часть 2: JavaScript, V8, некоторые приёмы разработки
Часть 3: Хостинг, REPL, работа с консолью, модули
Часть 4: npm, файлы package.json и package-lock.json
Часть 5: npm и npx
Часть 6: цикл событий, стек вызовов, таймеры
Часть 7: асинхронное программирование
Часть 8: Руководство по Node.js, часть 8: протоколы HTTP и WebSocket
Часть 9: Руководство по Node.js, часть 9: работа с файловой системой
Часть 10: Руководство по Node.js, часть 10: стандартные модули, потоки, базы данных, NODE_ENV
Полная PDF-версия руководства по Node.js

Работа с файловыми дескрипторами в Node.js

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

Дескриптор можно получить, воспользовавшись для открытия файла асинхронным методом open() из модуля fs:

const fs = require('fs')
fs.open('/Users/flavio/test.txt', 'r', (err, fd) => {
  //fd - это дескриптор файла
})

Обратите внимание на второй параметр, r, использованный при вызове метода fs.open(). Это — флаг, который сообщает системе о том, что файл открывают для чтения. Вот ещё некоторые флаги, которые часто используются при работе с этим и некоторыми другими методами:

  • r+ — открыть файл для чтения и для записи.
  • w+ — открыть файл для чтения и для записи, установив указатель потока в начало файла. Если файл не существует — он создаётся.
  • a — открыть файл для записи, установив указатель потока в конец файла. Если файл не существует — он создаётся.
  • a+ — открыть файл для чтения и записи, установив указатель потока в конец файла. Если файл не существует — он создаётся.

Файлы можно открывать и пользуясь синхронным методом fs.openSync(), который, вместо того, чтобы предоставить дескриптор файла в коллбэке, возвращает его:

const fs = require('fs')
try {
  const fd = fs.openSync('/Users/flavio/test.txt', 'r')
} catch (err) {
  console.error(err)
}

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

Данные о файлах

С каждым файлом связан набор данных о нём, исследовать эти данные можно средствами Node.js. В частности, сделать это можно, используя метод stat() из модуля fs.

Вызывают этот метод, передавая ему путь к файлу, и, после того, как Node.js получит необходимые сведения о файле, он вызовет коллбэк, переданный методу stat(). Вот как это выглядит:

const fs = require('fs')
fs.stat('/Users/flavio/test.txt', (err, stats) => {
  if (err) {
    console.error(err)
    return
  }
  //сведения о файле содержатся в аргументе `stats`
})

В Node.js имеется возможность синхронного получения сведений о файлах. При таком подходе главный поток блокируется до получения свойств файла:

const fs = require('fs')
try {
  const stats = fs.statSync ('/Users/flavio/test.txt')
} catch (err) {
  console.error(err)
}

Информация о файле попадёт в константу stats. Что это за информация? На самом деле, соответствующий объект предоставляет нам большое количество полезных свойств и методов:

  • Методы .isFile() и .isDirectory() позволяют, соответственно, узнать, является ли исследуемый файл обычным файлом или директорией.
  • Метод .isSymbolicLink() позволяет узнать, является ли файл символической ссылкой.
  • Размер файла можно узнать, воспользовавшись свойством .size.

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

const fs = require('fs')
fs.stat('/Users/flavio/test.txt', (err, stats) => {
  if (err) {
    console.error(err)
    return
  }
  stats.isFile() //true
  stats.isDirectory() //false
  stats.isSymbolicLink() //false
  stats.size //1024000 //= 1MB
})

Пути к файлам в Node.js и модуль path

Путь к файлу — это адрес того места в файловой системе, где он расположен.

В Linux и macOS путь может выглядеть так:

/users/flavio/file.txt

В Windows пути выглядят немного иначе:

C:usersflaviofile.txt

На различия в форматах записи путей при использовании разных операционных систем следует обращать внимание, учитывая операционную систему, используемую для развёртывания Node.js-сервера.

В Node.js есть стандартный модуль path, предназначенный для работы с путями к файлам. Перед использованием этого модуля в программе его надо подключить:

const path = require('path')

▍Получение информации о пути к файлу

Если у вас есть путь к файлу, то, используя возможности модуля path, вы можете, в удобном для восприятия и дальнейшей обработки виде, узнать подробности об этом пути. Выглядит это так:

const notes = '/users/flavio/notes.txt'
path.dirname(notes) // /users/flavio
path.basename(notes) // notes.txt
path.extname(notes) // .txt

Здесь, в строке notes, хранится путь к файлу. Для разбора пути использованы следующие методы модуля path:

  • dirname() — возвращает родительскую директорию файла.
  • basename() — возвращает имя файла.
  • extname() — возвращает расширение файла.

Узнать имя файла без расширения можно, вызвав метод .basename() и передав ему второй аргумент, представляющий расширение:

path.basename(notes, path.extname(notes)) //notes

▍Работа с путями к файлам

Несколько частей пути можно объединить, используя метод path.join():

const name = 'flavio'
path.join('/', 'users', name, 'notes.txt') //'/users/flavio/notes.txt'

Найти абсолютный путь к файлу на основе относительного пути к нему можно с использованием метода path.resolve():

path.resolve('flavio.txt') 
//'/Users/flavio/flavio.txt' при запуске из моей домашней папки

В данном случае Node.js просто добавляет /flavio.txt к пути, ведущем к текущей рабочей директории. Если при вызове этого метода передать ещё один параметр, представляющий путь к папке, метод использует его в качестве базы для определения абсолютного пути:

path.resolve('tmp', 'flavio.txt')
// '/Users/flavio/tmp/flavio.txt' при запуске из моей домашней папки

Если путь, переданный в качестве первого параметра, начинается с косой черты — это означает, что он представляет собой абсолютный путь.

path.resolve('/etc', 'flavio.txt')
// '/etc/flavio.txt'

Вот ещё один полезный метод — path.normalize(). Он позволяет найти реальный путь к файлу, используя путь, в котором содержатся спецификаторы относительного пути вроде точки (.), двух точек (..), или двух косых черт:

path.normalize('/users/flavio/..//test.txt') 
// /users/test.txt

Методы resolve() и normalize() не проверяют существование директории. Они просто находят путь, основываясь на переданным им данным.

Чтение файлов в Node.js

Самый простой способ чтения файлов в Node.js заключается в использовании метода fs.readFile() с передачей ему пути к файлу и коллбэка, который будет вызван с передачей ему данных файла (или объекта ошибки):

fs.readFile('/Users/flavio/test.txt', (err, data) => {
  if (err) {
    console.error(err)
    return
  }
  console.log(data)
})

Если надо, можно воспользоваться синхронной версией этого метода — fs.readFileSync():

const fs = require('fs')
try {
  const data = fs.readFileSync('/Users/flavio/test.txt')
  console.log(data)
} catch (err) {
  console.error(err)
}

По умолчанию при чтении файлов используется кодировка utf8, но кодировку можно задать и самостоятельно, передав методу соответствующий параметр.

Методы fs.readFile() и fs.readFileSync() считывают в память всё содержимое файла. Это означает, что работа с большими файлами с применением этих методов серьёзно отразится на потреблении памяти вашим приложением и окажет влияние на его производительность. Если с такими файлами нужно работать, лучше всего воспользоваться потоками.

Запись файлов в Node.js

В Node.js легче всего записывать файлы с использованием метода fs.writeFile():

const fs = require('fs')
const content = 'Some content!'
fs.writeFile('/Users/flavio/test.txt', content, (err) => {
  if (err) {
    console.error(err)
    return
  }
  //файл записан успешно
})

Есть и синхронная версия того же метода — fs.writeFileSync():

const fs = require('fs')
const content = 'Some content!'
try {
  const data = fs.writeFileSync('/Users/flavio/test.txt', content)
  //файл записан успешно
} catch (err) {
  console.error(err)
}

Эти методы, по умолчанию, заменяют содержимое существующих файлов. Изменить их стандартное поведение можно, воспользовавшись соответствующим флагом:

fs.writeFile('/Users/flavio/test.txt', content, { flag: 'a+' }, (err) => {})

Тут могут использоваться флаги, которые мы уже перечисляли в разделе, посвящённом дескрипторам. Подробности о флагах можно узнать здесь.

Присоединение данных к файлу

Метод fs.appendFile() (и его синхронную версию — fs.appendFileSync()) удобно использовать для присоединения данных к концу файла:

const content = 'Some content!'
fs.appendFile('file.log', content, (err) => {
  if (err) {
    console.error(err)
    return
  }
  //готово!
})

Об использовании потоков

Выше мы описывали методы, которые, выполняя запись в файл, пишут в него весь объём переданных им данных, после чего, если используются их синхронные версии, возвращают управление программе, а если применяются асинхронные версии — вызывают коллбэки. Если вас такое состояние дел не устраивает — лучше будет воспользоваться потоками.

Работа с директориями в Node.js

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

▍Проверка существования папки

Для того чтобы проверить, существует ли директория и может ли Node.js получить к ней доступ, учитывая разрешения, можно использовать метод fs.access().

▍Создание новой папки

Для того чтобы создавать новые папки, можно воспользоваться методами fs.mkdir() и fs.mkdirSync():

const fs = require('fs')
const folderName = '/Users/flavio/test'
try {
  if (!fs.existsSync(dir)){
    fs.mkdirSync(dir)
  }
} catch (err) {
  console.error(err)
}

▍Чтение содержимого папки

Для того чтобы прочесть содержимое папки, можно воспользоваться методами fs.readdir() и fs.readdirSync(). В этом примере осуществляется чтение содержимого папки — то есть — сведений о том, какие файлы и поддиректории в ней имеются, и возврат их относительных путей:

const fs = require('fs')
const path = require('path')
const folderPath = '/Users/flavio'
fs.readdirSync(folderPath)

Вот так можно получить полный путь к файлу:

fs.readdirSync(folderPath).map(fileName => {
  return path.join(folderPath, fileName)
}

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

const isFile = fileName => {
  return fs.lstatSync(fileName).isFile()
}
fs.readdirSync(folderPath).map(fileName => {
  return path.join(folderPath, fileName)).filter(isFile)
}

▍Переименование папки

Для переименования папки можно воспользоваться методами fs.rename() и fs.renameSync(). Первый параметр — это текущий путь к папке, второй — новый:

const fs = require('fs')
fs.rename('/Users/flavio', '/Users/roger', (err) => {
  if (err) {
    console.error(err)
    return
  }
  //готово
})

Переименовать папку можно и с помощью синхронного метода fs.renameSync():

const fs = require('fs')
try {
  fs.renameSync('/Users/flavio', '/Users/roger')
} catch (err) {
  console.error(err)
}

▍Удаление папки

Для того чтобы удалить папку, можно воспользоваться методами fs.rmdir() или fs.rmdirSync(). Надо отметить, что удаление папки, в которой что-то есть, задача несколько более сложная, чем удаление пустой папки. Если вам нужно удалять такие папки, воспользуйтесь пакетом fs-extra, который весьма популярен и хорошо поддерживается. Он представляет собой замену модуля fs, расширяющую его возможности.

Метод remove() из пакета fs-extra умеет удалять папки, в которых уже что-то есть.

Установить этот модуль можно так:

npm install fs-extra

Вот пример его использования:

const fs = require('fs-extra')
const folder = '/Users/flavio'
fs.remove(folder, err => {
  console.error(err)
})

Его методами можно пользоваться в виде промисов:

fs.remove(folder).then(() => {
  //готово
}).catch(err => {
  console.error(err)
})

Допустимо и применение конструкции async/await:

async function removeFolder(folder) {
  try {
    await fs.remove(folder)
    //готово
  } catch (err) {
    console.error(err)
  }
}
const folder = '/Users/flavio'
removeFolder(folder)

Модуль fs

Выше мы уже сталкивались с некоторыми методами модуля fs, применяемыми при работе с файловой системой. На самом деле, он содержит ещё много полезного. Напомним, что он не нуждается в установке, для того, чтобы воспользоваться им в программе, его достаточно подключить:

const fs = require('fs')

После этого у вас будет доступ к его методам, среди которых отметим следующие, некоторые из которых вам уже знакомы:

  • fs.access(): проверяет существование файла и возможность доступа к нему с учётом разрешений.
  • fs.appendFile(): присоединяет данные к файлу. Если файл не существует — он будет создан.
  • fs.chmod(): изменяет разрешения для заданного файла. Похожие методы: fs.lchmod(), fs.fchmod().
  • fs.chown(): изменяет владельца и группу для заданного файла. Похожие методы: fs.fchown(), fs.lchown().
  • fs.close(): закрывает дескриптор файла.
  • fs.copyFile(): копирует файл.
  • fs.createReadStream(): создаёт поток чтения файла.
  • fs.createWriteStream(): создаёт поток записи файла.
  • fs.link(): создаёт новую жёсткую ссылку на файл.
  • fs.mkdir(): создаёт новую директорию.
  • fs.mkdtemp(): создаёт временную директорию.
  • fs.open(): открывает файл.
  • fs.readdir(): читает содержимое директории.
  • fs.readFile(): считывает содержимое файла. Похожий метод: fs.read().
  • fs.readlink(): считывает значение символической ссылки.
  • fs.realpath(): разрешает относительный путь к файлу, построенный с использованием символов . и .., в полный путь.
  • fs.rename(): переименовывает файл или папку.
  • fs.rmdir(): удаляет папку.
  • fs.stat(): возвращает сведения о файле. Похожие методы: fs.fstat(), fs.lstat().
  • fs.symlink(): создаёт новую символическую ссылку на файл.
  • fs.truncate(): обрезает файл до заданной длины. Похожий метод: fs.ftruncate().
  • fs.unlink(): удаляет файл или символическую ссылку.
  • fs.unwatchFile(): отключает наблюдение за изменениями файла.
  • fs.utimes(): изменяет временную отметку файла. Похожий метод: fs.futimes().
  • fs.watchFile(): включает наблюдение за изменениями файла. Похожий метод: fs.watch().
  • fs.writeFile(): записывает данные в файл. Похожий метод: fs.write().

Интересной особенностью модуля fs является тот факт, что все его методы, по умолчанию, являются асинхронными, но существуют и их синхронные версии, имена которых получаются путём добавления слова Sync к именам асинхронных методов.

Например:

  • fs.rename()
  • fs.renameSync()
  • fs.write()
  • fs.writeSync()

Использование синхронных методов серьёзно влияет на то, как работает программа.

В Node.js 10 имеется экспериментальная поддержка этих API, основанных на промисах.

Исследуем метод fs.rename(). Вот асинхронная версия этого метода, использующая коллбэки:

const fs = require('fs')
fs.rename('before.json', 'after.json', (err) => {
  if (err) {
    return console.error(err)
  }
  //готово
})

При использовании его синхронной версии для обработки ошибок используется конструкция try/catch:

const fs = require('fs')
try {
  fs.renameSync('before.json', 'after.json')
  //готово
} catch (err) {
  console.error(err)
}

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

Модуль path

Модуль path, о некоторых возможностях которого мы тоже уже говорили, содержит множество полезных инструментов, позволяющих взаимодействовать с файловой системой. Как уже было сказано, устанавливать его не нужно, так как он является частью Node.js. Для того чтобы пользоваться им, его достаточно подключить:

const path = require('path')

Свойство path.sep этого модуля предоставляет символ, использующийся для разделения сегментов пути ( в Windows и / в Linux и macOS), а свойство path.delimiter даёт символ, используемый для отделения друг от друга нескольких путей (; в Windows и : в Linux и macOS).

Рассмотрим и проиллюстрируем примерами некоторые методы модуля path.

▍path.basename()

Возвращает последний фрагмент пути. Передав второй параметр этому методу можно убрать расширение файла.

require('path').basename('/test/something') //something
require('path').basename('/test/something.txt') //something.txt
require('path').basename('/test/something.txt', '.txt') //something

▍path.dirname()

Возвращает ту часть пути, которая представляет имя директории:

require('path').dirname('/test/something') // /test
require('path').dirname('/test/something/file.txt') // /test/something

▍path.extname()

Возвращает ту часть пути, которая представляет расширение файла:

require('path').extname('/test/something') // ''
require('path').extname('/test/something/file.txt') // '.txt'

▍path.isAbsolute()

Возвращает истинное значение если путь является абсолютным:

require('path').isAbsolute('/test/something') // true
require('path').isAbsolute('./test/something') // false

▍path.join()

Соединяет несколько частей пути:

const name = 'flavio'
require('path').join('/', 'users', name, 'notes.txt') //'/users/flavio/notes.txt'

▍path.normalize()

Пытается выяснить реальный путь на основе пути, который содержит символы, использующиеся при построении относительных путей вроде ., .. и //:

require('path').normalize('/users/flavio/..//test.txt') ///users/test.txt

▍path.parse()

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

  • root: корневая директория.
  • dir: путь к файлу, начиная от корневой директории
  • base: имя файла и расширение.
  • name: имя файла.
  • ext: расширение файла.

Вот пример использования этого метода:

require('path').parse('/users/test.txt')

В результате его работы получается такой объект:

{
  root: '/',
  dir: '/users',
  base: 'test.txt',
  ext: '.txt',
  name: 'test'
}

▍path.relative()

Принимает, в качестве аргументов, 2 пути. Возвращает относительный путь из первого пути ко второму, основываясь на текущей рабочей директории:

require('path').relative('/Users/flavio', '/Users/flavio/test.txt') //'test.txt'
require('path').relative('/Users/flavio', '/Users/flavio/something/test.txt') //'something/test.txt'

▍path.resolve()

Находит абсолютный путь на основе переданного ему относительного пути:

path.resolve('flavio.txt') 
//'/Users/flavio/flavio.txt' при запуске из моей домашней папки.

Итоги

Сегодня мы рассмотрели модули Node.js fs и path, которые используются для работы с файловой системой. В следующей части этой серии, на которой она завершается, мы обсудим модули os, events, http, поговорим о работе с потоками и с системами управления базами данных в Node.js.

Уважаемые читатели! Какими npm-пакетами вы пользуетесь при работе с файловой системой в Node.js?

Как используя fs.readFile() можно найти файл, если известно только его название, без расширения?

Например, есть код, ищущий картинку в папке:

fs.readFile(`${process.cwd()}/picture_db/${id}`, (err, data) => {
  console.log(data, err);
})

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

задан 27 фев 2021 в 12:13

kertAW's user avatar

1

Получить все файлы из папки и пробежаться по ним:

const fs = require('fs');

fs.readdir(`${process.cwd()}/picture_db/`, (err, files) => {
  const image = files.find((name) => {
    const unescapedId = id.replace(/[\/.+*?(){}^$]/g, '\$&');
    return new RegExp('^' + unescapedName + '(?=\.(png|jpg|jpeg|bmp|gif|svg|webp))$').test(name);
  });
  console.log(image);
});

или

const fs = require('fs');

fs.readdir(`${process.cwd()}/picture_db/`, (err, files) => {
  const image = files.find((name) => {
    const nameValue = name.split('.').slice(0, -1);
    return nameValue.join('.') === id;
  });
  console.log(image);
});

ответ дан 27 фев 2021 в 17:31

Ruslan Mart's user avatar

Ruslan MartRuslan Mart

8103 серебряных знака4 бронзовых знака

2

Доброго времени суток, друзья. Поговорим сегодня о работе с файлами в Node.js. Для работы с файлами используется модуль fs (сокращение от File System).

В этой статье мы рассмотрим следующие темы:

— Работа с файловыми дескрипторами;

— Работа с директориями;

— Создание новой папки;

— Чтение содержимого папки;

— Удаление папки;

— Получение системной информации о файле;

— Модуль path и путь к файлу;

— Получение имени, пути и расширения файла;

— Работа с путями файла;

— Переименование файла или директории;

— Чтение файла;

— Запись файла;

— Копирование файла;

— Удаление файла.

Для начала работы нам потребуется установленная Node.js. Подробную инструкцию по ее установке вы можете получить (тут). 

Прежде чем начать работу с модулем, его следует импортировать в рабочем файле. 

Пример:


const fs = require(‘fs');

Пробежимся по основным методам этого модуля и посмотрим на примерах как с ними можно работать.

Работа с файловыми дескрипторами  

Прежде чем двигаться дальше, давайте посмотрим на термины, о которых описано в статье ниже.

Файловый дескриптор — это неотрицательное целое число. Когда создается новый поток ввода-вывода, ядро возвращает процессу, создавшему поток ввода-вывода, его файловый дескриптор (Wikipedia).

Если излагать простыми словами, то при открытии файла мы получаем его дескриптор — это уникальный индикатор, благодаря которому мы можем отслеживать каждый файл отдельно и работать с ним. Для получения дескриптора файла в Node.js используются два метода: (1) асинхронный метод fs.open() и (2) синхронный fs.openSync(). К слову все методы в Node.js имеют синхронные и асинхронные реализации. Синхронные методы отмечены в название метода с окончанием Sync. В чем же разница между синхронным и асинхронным методами? Главное отличие — это порядок их выполнения. Синхронный метод будет выполнен путем блокирования основного потока, в тоже время, если для того же действия использовать ассинхронный метод, то операции могут быть выполнены в произвольном порядке по истечению их выполнения (т.к. основной поток не будет блокироваться).

Перейдем к примерам.


const fs = require('fs')

// асинхронный
fs.open('template.txt', 'r', (err, fd) => {
    if (err) throw err;
    //fd - это дескриптор файла
    console.log(fd)
})

// синхронный 
try {
  const fd = fs.openSync('template.txt', 'r')
  console.log(fd)
} catch (err) {
  console.error(err)
}

В этих примерах при выполнении кода, мы получим уникальный дескриптор файла. Пройдемся по параметрам методов. Первый — это путь к файлу, который читаем. Второй параметр предназначен для передачи флагов доступа к файлам. В данном примере мы указали параметр ‘r’, что означает этот файл открыт для чтения.

Ниже я приведу перечень флагов доступа к файлам

r — чтение;

r+ — чтение и запись;

w+ — чтение и запись, запись с начала файла. Файл создается если его нет;

a —  запись, запись с конца файла. Файл создается если его нет;

a + — чтение и запись, запись с конца файла. Файл создается если его нет;

Третий параметр отличается в зависимости от типа метода. В асинхронном варианте это колбэк функция, первый аргумент которой возвращает ошибку (в случае ее возникновения), а второй — сам дескриптор. Если метод синхронный, то вызов происходит в блоке try/catch для отслеживания ошибок и получения ответа путем присвоения вызова переменной.

Следует помнить, что дескрипторы файлов необходимо закрывать для предотвращения переполнения памяти, а также проблем с производительностью. Выполним данную задачу с помощью метода close() и его синхронного аналога closeSync().

Работа с директориями 

Для проверки существующей директории (файла) и доступов к нему в модуле fs применяется метод access

Пример:


const fs = require('fs')
const file = 'package.json';

// проверка существования файла
fs.access(file, fs.constants.F_OK, (err) => {
  console.log(`${file} ${err ? 'не существует' : 'существует'}`);
});

// проверка на возможность прочитать файл
fs.access(file, fs.constants.R_OK, (err) => {
    console.log(`${file} ${err ? 'не прочитать' : 'прочитать'}`);
});
  
// проверка на возможность перезаписать файл
fs.access(file, fs.constants.W_OK, (err) => {
    console.log(`${file} ${err ? 'не перезаписать' : 'перезаписать'}`);
});

Вторым параметром устанавливается константа режима проверки:

F_OK — существование файла без проверки прав доступа;

R_OK — может ли файл быть прочитан текущим процессом;

W_OK — может ли файл быть записан текущим процессом;

X_OK — может ли файл быть выполнен текущим процессом (в Windows не работает).

Создание новой папки

Для создания каталогов присутствует асинхронный метод mkdir и синхронный mkdirSync.

Пример:


fs.mkdir(__dirname + dir, { recursive: true }, (err) => {
    if (err) {
        console.error(err)
        return
    }
})

if (!fs.existsSync(dir)) {
    try {
      fs.mkdirSync(__dirname + dir, { recursive: true })
    } catch (error) {
        console.error(error)
    }
} else {
    console.log('Папка существует')
}

Для создания в текущей директории нового каталога, перед путем следует указать переменную __dirname как вариант реализации абсолютного пути, либо воспользоваться метом resolve модуля path.

Чтение содержимого папки 

Для получения содержимого директории используются два метода readdir и readdirSync. Первым параметром для методов передается путь директории, содержимое которой нужно получить.

Пример:


const fs = require('fs')
const dir =  __dirname + '/'

fs.readdir(dir, (err, files) => {
    if (err) {
      console.error(err)
      return
    }
    console.log(files)
})

try {
    const files = fs.readdirSync(dir)
    console.log(files)
} catch (error) {
      console.error(error)
}

Удаление папки

Удаление директории производится с помощью методов rmdir и rmdirSync. Первым параметром методов является путь удаляемой директории.

Пример:


const fs = require('fs')

fs.rmdir(__dirname +'/testDel', () => { 
    console.log('Файл успешно удален')
})

try {
    fs.rmdirSync(__dirname + '/testDel')
    console.log('Файл успешно удален')
} catch (error) {
    console.error(error)
}

Получение системной информации о файле 

Каждый файл, который мы загружаем, помимо данных хранит в себе системную информацию. Для получения этой информации можно воспользоваться методом stat() или выбрать синхронный вариант statSync()

Пример:


// асинхронный
fs.stat('template.txt', (err, stats) => {
    if (err) {
        console.error(err)
        return
    }
    console.log(stats)
})

// синхронный
try {
  const stats = fs.statSync('template.txt')
  console.log(stats)
} catch (err) {
  console.error(err)
}

Вся информация хранится в получаемом объекте stats. Данный объект хранит в себе методы для получения дополнительной полезной информации.

Перечислю некоторые из этих свойств:

stats.isDirectory() метод позволяет узнать, является ли файл директорией;

stats.isFile() метод возвращает true, если это файл;

stats.isSocket() метод возвращает true, если это сокет;

stats.isSymbolicLink() метод возвращает true, если файл является символьной ссылкой;

stats.size свойство, которое возвращает размер файла;

stats.birthtime возвращает время и дату, когда данный файл был создан.

Пример: 


fs.stat('template.txt', (err, stats) => {
    if (err) {
        console.error(err)
        return
    }
    console.log(stats.isDirectory())
    console.log(stats.isFile())
    console.log(stats.isSocket())
    console.log(stats.isSymbolicLink())
    console.log(stats.size)
    console.log(stats.mode)
    console.log(stats.birthtime)
})

Модуль path и путь к файлу Node.js

Основной проблемой при работе с файлами и папками в операционных системах является разный синтаксис написания путей их расположения. Для решения этой проблемы в Node.js есть модуль path c набором полезных методов.

Для началы работы с модулем его нужно импортировать.

Пример:


const path = require(‘path');

Получение имени, пути и расширения файла

Предположим, что в папке /temp лежит файл template.txt. Воспользуемся методами модуля path для получения имени файла, пути к нему, а так же его расширения. 

Пример:


const file = ‘/temp/tempalate.txt'

path.basename(file) // tempalate.txt

Метод basename возвращает наименование файла. Первым параметром передается путь к файлу, вторым параметром (опционально) передается расширение файла, если необходимо получить наименование файла без расширения.

Пример:


path.basename(file, ‘.txt’) // tempalate

path.basename(file, ‘.txt’) // tempalate

Метод dirname возвращает весь путь директории, где лежит файл и имеет один параметр, в который передается путь к файлу.

Пример:


path.dirname(file) // /temp

Метод extname возвращает расширение переданного файла.

Пример:


path.extname(file) // .txt

Работа с путями файла

В модуле path есть ряд методов для удобного формирования путей к нужному файлу или директории. Мы не будем рассматривать все методы, а только наиболее часто используемые. Рассмотрим их ниже.

Метод join принимает список параметров, объединяет их в одну строку, используя разделитель, подходящий к конкретной операционной системе, в которой будет исполнятся код.

Пример:


const folderName = 'temp'
path.join('/', folderName, ‘template.txt') // /temp/template.txt

Метод resolve используется для нахождения абсолютных путей к файлу.

Пример:


path.resolve(‘template.txt') // Users/Desktop/dev/node-fs/template.txt
path.resolve(folderName, ‘template.txt’) // /Users/Desktop/dev/node-fs/temp/template.txt
path.resolve('/temp', ‘template.txt') // /temp/template.txt

Метод normalize позволяет найти путь к файлу, используя синтаксис переходов (.. и .) по папкам.

Пример:


path.normalize(‘/users/../temp/template.txt')
// temp/template.txt

Переименование файла или директории

Методы rename() и renameSync() первым параметром принимают путь к файлу, который нужно переименовать. Второй параметр отвечает за новое наименование файла. 

Пример:


const fs = require('fs')

// переименовываем файла
fs.rename('oldFile.txt', 'newFile.txt', (err) => {
    if (err) throw err;
    console.log('Файл переименован');
});

// переименовываем директорию
try {
    fs.renameSync('./oldDir', './newDir')
    console.log('Папка переименован');
} catch (error) {
      console.error(error)
}

Чтение файла

Пример:


const fs = require('fs')

// асинхронное
fs.readFile(‘template.txt', ‘utf-8’, (err, data) => {
    if (err) {
      console.error(err)
      return
    }
    console.log(data)
})

// синхронное
try {
    const data = fs.readFileSync(‘template.txt', 'utf-8')
    console.log(data)
} catch (err) {
    console.error(err)
}

Если вторым параметром не указана кодировка, то возвращается Buffer. Эти методы полностью загружают файлы в память компьютера, что может сильно отразиться на производительности. Если размер файла большой, то стоит воспользоваться потоками fs.createReadStream()

Запись файла 

Чтобы перезаписать контент файлов, используются методы writeFile и writeFileSync. Важный момент! Если файла, контент которого нужно перезаписать, не существует, то он будет создан автоматически.

Пример:


const fs = require('fs')
const content = 'Новый текст'

fs.writeFile('newText.txt', content, (err) => {
  if (err) {
    console.error(err)
    return
  }
  console.log('файл успешно перезаписан')
})

try {
    fs.writeFileSync('newTextTwo.txt', content)
    console.log('файл успешно перезаписан')
} catch (err) {
    console.error(err)
}

Копирование файла 

Методы copyFile() и copyFileSync() первым параметром принимают путь файла для копирования. Второй параметр принимает название пути и нового файла. Третьим параметром является колбэк функция, которая возвращает ошибку.

Пример:


const fs = require('fs')

fs.copyFile('oldFile.txt', 'oldFileTwo.txt', (err) => {
    if (err) {
        console.error(err)
        return
    }
    console.log('Файл успешно копирован')
});

try {
    fs.copyFileSync('oldFile.txt', 'oldFileTwo.txt')
    console.log('Файл успешно копирован')
} catch (error) {
    console.error(error)
}

Удаление файла 

Последнее, что мы рассмотрим в этой статье будут методы unlink() и unlinkSync(). Первым параметром методы принимают путь к удаляемому файлу. Второй параметр в методе unlink возвращает колбэк функцию с ошибкой.

Пример:


const fs = require('fs')

fs.unlink('file.txt', (err) => {
    if (err) throw err;
    console.log('Файл успешно удален');
});

try {
    fs.unlinkSync('file.txt')
    console.log('Файл успешно удален');
} catch (error) {
    console.error(error)
}

Заключение

В данной статье мы разобрали работу Node.js с файлами, на примерах посмотрели основные полезные методы модулей fs и path. Исходный код вы сможете найти тут. Надеюсь данная статья была вам полезна. Учитесь, думайте, пишите код. Удачного кодинга, друзья!

Полезные ссылки:

https://nodejs.org/en/ — официальный сайт node.js

Подписывайтесь на наш канал в Telegram и на YouTube для получения самой последней и актуальной информации. 

что я делаю: [Предполагая, что у вас есть доступ к исходному коду]

grep -r "function someFunction" . 

где . — это каталог, в котором начинается рекурсивный поиск шаблона. Он покажет вам все файлы, содержащие шаблон «function someFunction».

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

grep -r "function someFunction" | grep -v "withouth this text"

надеюсь, что это поможет! на окнах, возможно, вы можете использовать это с cygwin?

Это, конечно, не будет работать, если someFunction размещен на внешнем хосте…

Node.js FS — Файловая система

От автора: Node реализует ввод/вывод файлов с использованием простых оболочек для стандартных функций POSIX. Модуль Node js FS (File System) может быть импортирован с помощью синтаксиса, представленного ниже.

Синхронная и асинхронная формы

Каждый метод в модуле fs имеет как синхронную, так и асинхронную форму. Асинхронные методы принимают в качестве последнего параметра функции обратного вызова завершения и в качестве первого параметра функции обратного вызова — ошибки. Более эффективным является использование асинхронного метода, поскольку он не блокирует программу во время ее выполнения.

Профессия Frontend-разработчик PRO

Готовим Frontend-разработчиков с нуля

На курсе вы научитесь создавать интерфейсы веб-сервисов с помощью языков программирования и
дополнительных технологий. Сможете разрабатывать планировщики задач, мессенджеры, интернет-магазины…

Узнать подробнее

До 10 проектов в портфолио для старта карьеры

Подходит для новичков без опыта в программировании

Практика на вебинарах с разработчиками из крупных компаний

Пример

Создайте текстовый файл с именем input.txt со следующим содержимым:

Tutorials Point is giving self learning content

to teach the world in simple and easy way!!!!!

Создайте файл js с именем main.js со следующим кодом:

var fs = require(«fs»);

// Asynchronous read

fs.readFile(‘input.txt’, function (err, data) {

   if (err) {

      return console.error(err);

   }

   console.log(«Asynchronous read: « + data.toString());

});

// Synchronous read

var data = fs.readFileSync(‘input.txt’);

console.log(«Synchronous read: « + data.toString());

console.log(«Program Ended»);

Теперь запустите main.js:

В результате вы должны получить следующее.

Synchronous read: Tutorials Point is giving self learning content

to teach the world in simple and easy way!!!!!

Program Ended

Asynchronous read: Tutorials Point is giving self learning content

to teach the world in simple and easy way!!!!!

В следующих разделах этой главы представлен набор практических примеров основных методов для работы с файлами.

Открытие файла

Синтаксис. Ниже приведен синтаксис метода для открытия файла в асинхронном режиме:

fs.open(path, flags[, mode], callback)

Параметры

Ниже приводится описание используемых параметров —

path — это строка с именем файла, включая путь к нему.

flags — указывают режим работы с файлом, который нужно открыть. Все возможные значения приведены ниже.

mode — устанавливает режим файла (права доступа), но только если файл был создан. По умолчанию — 0666, чтение и запись.

callback — это функция обратного вызова, которая принимает два аргумента (err, fd).

Flags

Флаги для операций чтения/записи –

r — Открыть файл для чтения. Если файл не существует, добавляется исключение.

г+ — Открыть файл для чтения и записи. Если файл не существует, добавляется исключение.

rs — Открыть файл для чтения в синхронном режиме.

rs+ — Открыть файл для чтения и записи, запросив у ОС открыть его в синхронном режиме. Смотрите примечания для «rs» относительно использования данного флага.

w — Открыть файл для записи. Файл создается (если он не существует) или усекается (если он существует).

wx — Работает так же как «w», но не выполняется, если путь существует.

w+ — Открыть файл для чтения и записи. Если файл не существует, он создается, если файл существует, он усекается.

wx+ — Работает так же как «w+», но не выполняется, если путь существует.

a — Открыть файл для дополнения. Если файл не существует, он создается.

ax — Работает как «а», но не выполняется, если путь существует.

a+ — Открыть файл для чтения и расширения. Если файл не существует, он создается.

ах+ — Работает так же как «a+», но не выполняется, если путь существует.

Пример

Создайте файл js с именем main.js, содержащий следующий код, чтобы открыть файл input.txt для чтения и записи.

var fs = require(«fs»);

// Asynchronous — Opening File

console.log(«Going to open file!»);

fs.open(‘input.txt’, ‘r+’, function(err, fd) {

   if (err) {

      return console.error(err);

   }

  console.log(«File opened successfully!»);    

});

Теперь запустите main.js:

В результате вы должны получить следующее.

Going to open file!

File opened successfully!

Получение информации о файлах

Синтаксис. Ниже приведен синтаксис метода для получения информации о файле:

Параметры

Ниже приводится описание используемых параметров —

path — это строка с именем файла, включая путь к нему.

callback — это функция обратного вызова, которая принимает два аргумента (err, stats), где stats — это объект типа fs.Stats, который приведен в примере ниже.

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

stats.isFile() — Возвращает true, если тип файла — простой файл.

stats.isDirectory() — Возвращает true, если тип файла — каталог.

stats.isBlockDevice() — Возвращает true, если тип файла — блочное устройство.

stats.isCharacterDevice() — Возвращает true, если тип файла — символьное устройство.

stats.isSymbolicLink() — Возвращает true, если тип файла — символьная ссылка.

stats.isFIFO() — Возвращает true, если тип файла — FIFO.

stats.isSocket() — Возвращает true, если тип файла — сокет.

Пример

Создайте файл js с именем main.js со следующим кодом:

var fs = require(«fs»);

console.log(«Going to get file info!»);

fs.stat(‘input.txt’, function (err, stats) {

   if (err) {

       return console.error(err);

   }

   console.log(stats);

   console.log(«Got file info successfully!»);

   // Check file type

   console.log(«isFile ? « + stats.isFile());

   console.log(«isDirectory ? « + stats.isDirectory());    

});

Теперь запустите main.js:

В результате вы должны получить следующее.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Going to get file info!

{

   dev: 1792,

   mode: 33188,

   nlink: 1,

   uid: 48,

   gid: 48,

   rdev: 0,

   blksize: 4096,

   ino: 4318127,

   size: 97,

   blocks: 8,

   atime: Sun Mar 22 2015 13:40:00 GMT0500 (CDT),

   mtime: Sun Mar 22 2015 13:40:57 GMT0500 (CDT),

   ctime: Sun Mar 22 2015 13:40:57 GMT0500 (CDT)

}

Got file info successfully!

isFile ? true

isDirectory ? false

Запись файла

Синтаксис. Ниже приведен синтаксис одного из способов записи в файл:

fs.writeFile(filename, data[, options], callback)

Этот метод перезаписывает файл, если файл уже существует. Если вы хотите дописать что-то в существующий файл, вы должны использовать другой доступный метод.

Параметры

Ниже приводится описание используемых параметров —

path — это строка с именем файла, включая путь к нему.

data – это строка или буфер, которые должны быть записаны в файл.

options — Третий параметр — это объект, который содержит {encoding, mode, flag}. По умолчанию encoding — utf8, mode — восьмеричное значение 0666 и flag — w,

callback — это функция обратного вызова, которая получает единственный параметр err, который возвращает ошибку в случае возникновения ошибки записи.

Пример

Создайте файл js с именем main.js, содержащий следующий код —

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

var fs = require(«fs»);

console.log(«Going to write into existing file»);

fs.writeFile(‘input.txt’, ‘Simply Easy Learning!’,  function(err) {

   if (err) {

      return console.error(err);

   }

   console.log(«Data written successfully!»);

   console.log(«Let’s read newly written data»);

   fs.readFile(‘input.txt’, function (err, data) {

      if (err) {

         return console.error(err);

      }

      console.log(«Asynchronous read: « + data.toString());

   });

});

Теперь запустите main.js:

В результате вы получите следующее.

Going to write into existing file

Data written successfully!

Lets read newly written data

Asynchronous read: Simply Easy Learning!

Чтение файла

Синтаксис. Ниже приведен синтаксис одного из методов чтения из файла:

fs.read(fd, buffer, offset, length, position, callback)

Этот метод использует для чтения файла файловый дескриптор. Если вы хотите считать файл напрямую, с помощью имени файла, используйте другой метод.

Параметры

Ниже приводится описание используемых параметров:

fd — это дескриптор файла, возвращаемый функцией fs.open().

buffer — это буфер, в который будут записаны данные.

offset — это смещение в буфере к позиции начала записи.

length — это целое число, определяющее количество прочитанных байтов.

position — Это целое число, указывающее, с какой позиции должно начинаться чтение файла. Если позиция равна нулю, данные будут считываться с текущей позиции файла.

callback — это функция обратного вызова, которая принимает три аргумента (err, bytesRead, buffer).

Пример

Создайте файл js с именем main.js со следующим кодом:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

var fs = require(«fs»);

var buf = new Buffer(1024);

console.log(«Going to open an existing file»);

fs.open(‘input.txt’, ‘r+’, function(err, fd) {

   if (err) {

      return console.error(err);

   }

   console.log(«File opened successfully!»);

   console.log(«Going to read the file»);

   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){

      if (err){

         console.log(err);

      }

      console.log(bytes + » bytes read»);

      // Print only read bytes to avoid junk.

      if(bytes > 0){

         console.log(buf.slice(0, bytes).toString());

      }

   });

});

Теперь запустите main.js:

В результате вы должны получить следующее.

Going to open an existing file

File opened successfully!

Going to read the file

97 bytes read

Tutorials Point is giving self learning content

to teach the world in simple and easy way!!!!!

Закрытие файла

Синтаксис. Ниже приведен синтаксис для закрытия открытого файла:

Параметры

Ниже приводится описание используемых параметров —

fd — это дескриптор файла, возвращаемый методом fs.open().

callback — это функция обратного вызова. функции обратного вызова завершения не передаются никакие аргументы, кроме возможных исключений.

Пример

Создайте файл js с именем main.js, содержащий следующий код:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

var fs = require(«fs»);

var buf = new Buffer(1024);

console.log(«Going to open an existing file»);

fs.open(‘input.txt’, ‘r+’, function(err, fd) {

   if (err) {

      return console.error(err);

   }

   console.log(«File opened successfully!»);

   console.log(«Going to read the file»);

   fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){

      if (err){

         console.log(err);

      }

      // Print only read bytes to avoid junk.

      if(bytes > 0){

         console.log(buf.slice(0, bytes).toString());

      }

      // Close the opened file.

      fs.close(fd, function(err){

         if (err){

            console.log(err);

         }

         console.log(«File closed successfully.»);

      });

   });

});

Теперь запустите main.js:

В результате вы должны получить следующее.

Going to open an existing file

File opened successfully!

Going to read the file

Tutorials Point is giving self learning content

to teach the world in simple and easy way!!!!!

File closed successfully.

Усечение файла

Синтаксис. Ниже приведен синтаксис метода усечения открытого файла:

fs.ftruncate(fd, len, callback)

Параметры

Ниже приводится описание используемых параметров —

fd — это дескриптор файла, возвращаемый функцией fs.open().

len — длина файла, до которой он будет усечен.

callback — это функция обратного вызова. Никакие аргументы кроме возможных исключений не передаются функции обратного вызова завершения.

Пример

Создайте файл js с именем main.js, содержащий следующий код:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

var fs = require(«fs»);

var buf = new Buffer(1024);

console.log(«Going to open an existing file»);

fs.open(‘input.txt’, ‘r+’, function(err, fd) {

   if (err) {

      return console.error(err);

   }

   console.log(«File opened successfully!»);

   console.log(«Going to truncate the file after 10 bytes»);

   // Truncate the opened file.

   fs.ftruncate(fd, 10, function(err){

      if (err){

         console.log(err);

      }

      console.log(«File truncated successfully.»);

      console.log(«Going to read the same file»);

      fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){

         if (err){

            console.log(err);

         }

         // Print only read bytes to avoid junk.

         if(bytes > 0){

            console.log(buf.slice(0, bytes).toString());

         }

         // Close the opened file.

         fs.close(fd, function(err){

            if (err){

               console.log(err);

            }

            console.log(«File closed successfully.»);

         });

      });

   });

});

Теперь запустите main.js:

В результате вы должны получить следующее.

Going to open an existing file

File opened successfully!

Going to truncate the file after 10 bytes

File truncated successfully.

Going to read the same file

Tutorials

File closed successfully.

Удаление файла

Синтаксис. Ниже приведен синтаксис метода для удаления файла:

fs.unlink(path, callback)

Параметры

Ниже приводится описание используемых параметров —

path — это имя файла, включая путь к нему.

callback — это функция обратного вызова. Никакие аргументы кроме возможных исключений не передаются функции обратного вызова завершения.

Пример

Создадим файл js с именем main.js, содержащий следующий код:

var fs = require(«fs»);

console.log(«Going to delete an existing file»);

fs.unlink(‘input.txt’, function(err) {

   if (err) {

      return console.error(err);

   }

   console.log(«File deleted successfully!»);

});

Теперь запустите main.js:

В результате вы должны получить следующее.

Going to delete an existing file

File deleted successfully!

Создание директории

Синтаксис. Ниже приведен синтаксис метода для создания директории:

fs.mkdir(path[, mode], callback)

Параметры

Ниже приводится описание используемых параметров —

path — это имя директории, включая путь к ней.

mode – это права доступа к директории. По умолчанию — 0777.

callback — это функция обратного вызова. Никакие аргументы кроме возможных исключений не передаются функции обратного вызова завершения.

Пример

Создайте файл js с именем main.js, имеющий следующий код:

var fs = require(«fs»);

console.log(«Going to create directory /tmp/test»);

fs.mkdir(‘/tmp/test’,function(err){

   if (err) {

      return console.error(err);

   }

   console.log(«Directory created successfully!»);

});

Теперь запустите main.js —

В результате вы получите следующее.

Going to create directory /tmp/test

Directory created successfully!

Чтение директории

Синтаксис. Ниже приведен синтаксис метода для чтения директории —

fs.readdir(path, callback)

Параметры

Ниже приводится описание используемых параметров:

path — это имя директории, включая путь к ней.

callback — это функция обратного вызова, которая принимает два аргумента (err, files), где files — это массив имен файлов в директории, не включающих «.», а также ‘..’.

Пример

Создайте файл js с именем main.js, имеющий следующий код:

var fs = require(«fs»);

console.log(«Going to read directory /tmp»);

fs.readdir(«/tmp/»,function(err, files){

   if (err) {

      return console.error(err);

   }

   files.forEach( function (file){

      console.log( file );

   });

});

Теперь запустите main.js:

В результате вы должны получить следующее.

Going to read directory /tmp

ccmzx99o.out

ccyCSbkF.out

employee.ser

hsperfdata_apache

test

test.txt

Удаление директории

Синтаксис. Ниже приведен синтаксис метода для удаления директории:

Параметры

Ниже приводится описание используемых параметров:

path — это имя директории, включая путь к ней.

callback — это функция обратного вызова. Никакие аргументы кроме возможных исключений не передаются функции обратного вызова завершения.

Пример

Создайте файл js с именем main.js, имеющий следующий код —

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

var fs = require(«fs»);

console.log(«Going to delete directory /tmp/test»);

fs.rmdir(«/tmp/test»,function(err){

   if (err) {

      return console.error(err);

   }

   console.log(«Going to read directory /tmp»);

   fs.readdir(«/tmp/»,function(err, files){

      if (err) {

         return console.error(err);

      }

      files.forEach( function (file){

         console.log( file );

      });

   });

});

Теперь запустите main.js:

В результате вы должны получить следующее.

Going to read directory /tmp

ccmzx99o.out

ccyCSbkF.out

employee.ser

hsperfdata_apache

test.txt

Источник: //www.tutorialspoint.com/

Профессия Frontend-разработчик PRO

Готовим Frontend-разработчиков с нуля

На курсе вы научитесь создавать интерфейсы веб-сервисов с помощью языков программирования и
дополнительных технологий. Сможете разрабатывать планировщики задач, мессенджеры, интернет-магазины…

Узнать подробнее

До 10 проектов в портфолио для старта карьеры

Подходит для новичков без опыта в программировании

Практика на вебинарах с разработчиками из крупных компаний

Редакция: Команда webformyself.

Понравилась статья? Поделить с друзьями:
  • Как найти энергию спектра
  • Как исправить эту ошибку fatal error
  • Рекомендованное разрешение изображения как найти
  • Что такое обособленное приложение как его найти
  • Как найти трек по видео на ютубе