Перейти к содержимому

Что значит rb в python

  • автор:

Файлы. Работа с файлами.

Python 3 логотип

В данной статье мы рассмотрим встроенные средства python для работы с файлами: открытие / закрытие, чтение и запись.

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

У функции open много параметров, они указаны в статье "Встроенные функции", нам пока важны 3 аргумента: первый, это имя файла. Путь к файлу может быть относительным или абсолютным. Второй аргумент, это режим, в котором мы будем открывать файл.
Режим Обозначение
‘r’ открытие на чтение (является значением по умолчанию).
‘w’ открытие на запись, содержимое файла удаляется, если файла не существует, создается новый.
‘x’ открытие на запись, если файла не существует, иначе исключение.
‘a’ открытие на дозапись, информация добавляется в конец файла.
‘b’ открытие в двоичном режиме.
‘t’ открытие в текстовом режиме (является значением по умолчанию).
‘+’ открытие на чтение и запись

Режимы могут быть объединены, то есть, к примеру, ‘rb’ — чтение в двоичном режиме. По умолчанию режим равен ‘rt’.

И последний аргумент, encoding, нужен только в текстовом режиме чтения файла. Этот аргумент задает кодировку.

Чтение из файла

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

Первый — метод read, читающий весь файл целиком, если был вызван без аргументов, и n символов, если был вызван с аргументом (целым числом n).

Ещё один способ сделать это — прочитать файл построчно, воспользовавшись циклом for:

Запись в файл

Теперь рассмотрим запись в файл. Попробуем записать в файл вот такой вот список:

Откроем файл на запись:

 Запись в файл осуществляется с помощью метода write:
 

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

 Теперь попробуем воссоздать этот список из получившегося файла. Откроем файл на чтение (надеюсь, вы поняли, как это сделать?), и прочитаем строки.
   Мы получили тот же список, что и был. В более сложных случаях (словарях, вложенных кортежей и т. д.) алгоритм записи придумать сложнее. Но это и не нужно. В python уже давно придумали средства, такие как pickle или json, позволяющие сохранять в файле сложные структуры.

Для вставки кода на Python в комментарий заключайте его в теги

  • Модуль csv - чтение и запись CSV файлов
  • Создаём сайт на Django, используя хорошие практики. Часть 1: создаём проект
  • Онлайн-обучение Python: сравнение популярных программ
  • Книги о Python
  • GUI (графический интерфейс пользователя)
  • Курсы Python
  • Модули
  • Новости мира Python
  • NumPy
  • Обработка данных
  • Основы программирования
  • Примеры программ
  • Типы данных в Python
  • Видео
  • Python для Web
  • Работа для Python-программистов
  • Сделай свой вклад в развитие сайта!
  • Самоучитель Python
  • Карта сайта
  • Отзывы на книги по Python
  • Реклама на сайте

Класс FileResponse в Django что означает строка 'rb'?

Учу django, и появился вопрос на Отправка файлов, класс FileResponse . Вот пример:
.
filename = r'c:/irnages/irnage.png'
return FileResponse(open(filename, 'rb'))
Что означает строка 'rb' и какая у нее функция, какой параметр она задает в данном случае ? Нигде не могу найти обьяснение?

  • Вопрос задан более трёх лет назад
  • 304 просмотра

Комментировать

Решения вопроса 1

Сергей Горностаев @sergey-gornostaev Куратор тега Django

Седой и строгий

Сначала нужно выучить Python, потом браться за Django.

Ответ написан более трёх лет назад

Нравится 2 1 комментарий

Artem11111 @Artem11111 Автор вопроса

Понял, спасибо.

Ответы на вопрос 1

Full stack Python (Django) web-developer

Выражение open(filename, 'rb') означает открыть файл в бинарном (read-binaryy) режиме.

Ответ написан более трёх лет назад

Комментировать

Нравится 1 Комментировать

Ваш ответ на вопрос

Войдите, чтобы написать ответ

django

  • Django

Ошибка сохранения после переопределения метода POST в DJANGO?

  • 1 подписчик
  • 24 окт.
  • 68 просмотров

Функция open() в Python, открывает файл на чтение/запись

Открывает файл для чтения или записи файлового потока

Синтаксис:
fp = open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 
Параметры:
  • file - абсолютное или относительное значение пути к файлу или файловый дескриптор открываемого файла.
  • mode - необязательно, строка, которая указывает режим, в котором открывается файл. По умолчанию 'r' .
  • buffering - необязательно, целое число, используемое для установки политики буферизации.
  • encoding - необязательно, кодировка, используемая для декодирования или кодирования файла.
  • errors - необязательно, строка, которая указывает, как должны обрабатываться ошибки кодирования и декодирования. Не используется в -бинарном режиме
  • newline - необязательно, режим перевода строк. Варианты: None , '\n' , '\r' и '\r\n' . Следует использовать только для текстовых файлов.
  • closefd - необязательно, bool , флаг закрытия файлового дескриптора.
  • opener - необязательно, пользовательский объект, возвращающий открытый дескриптор файла.
Возвращаемое значение:
Описание:

Функция open() открывает файл для чтения или записи при помощи файлового потока. Если файл не может быть открыт, бросается исключение OSError .

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

Аргумент file - это строка, определяющая абсолютное или относительное расположение открываемого файла в файловой системе или целочисленный файловый дескриптор файла. Если задан файловый дескриптор, он закрывается, когда возвращаемый файловый поток закрывается, если для closefd не установлено значение False .

Изменено в Python 3.6: В аргумент file добавлена ​​поддержка приема объектов, реализующих os.PathLike . Обратите внимание, что модуль pathlib реализует протокол os.PathLike .

Аргумент mode - это необязательная строка, которая указывает режим, в котором открывается файл. По умолчанию 'r' , это означает, что файл открыт для чтения в текстовом режиме. Другими распространенными значениями являются 'w' для записи (очищает файл, если он уже существует), 'x' для монопольного создания и 'a' для добавления (что в некоторых системах Unix означает, что все операции записи добавляются в конец файла) независимо от текущей позиции указателя файла). В текстовом режиме, если кодировка не указана, используемая кодировка зависит от платформы: вызывается locale.getencoding() для получения текущей кодировки локали. (Для чтения и записи необработанных байтов нужно использовать двоичный режим и оставить кодировку неуказанной.) Доступны следующие режимы:

Значения аргумента mode :

  • r - открывает файл только для чтения,
  • w - открыт для записи (перед записью файл будет очищен),
  • x - эксклюзивное создание, бросается исключение FileExistsError , если файл уже существует.
  • a - открыт для добавления в конец файла (на некоторых Unix-системах пишет в конец файла вне зависимости от позиции курсора)
  • + - символ обновления (чтение + запись).
  • t - символ текстового режима.
  • b - символ двоичного режима (для операционных систем, которые различают текстовые и двоичные файлы).

Режим по умолчанию 'r' , открывает файл только для чтения текста, синоним 'rt' . Режимы 'r+' и 'r+b' открывают файл и устанавливают курсор на начало файла, запись в файл начинается с места остановки курсора при его чтении перед записью. Если файл перед записью не читался то запись осуществляется в начало файла. Режимы 'w' и 'wb' создают новый файл или открывают существующий файл только для записи, с последующей его очисткой (стирает все перед записью). У режимов 'w+' и 'wb+' поведение такое же как в предыдущем случае, только если не закрывать файл после записи, его еще можно потом прочитать.

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

  • 'r' - Открывает файл только для чтения. Указатель файла помещается в начале файла. Это режим "по умолчанию".
  • 'rb' - Открывает файл в бинарном режиме только для чтения. Указатель файла помещается в начале файла. Это режим "по умолчанию".
  • 'r+' - Открывает файл для чтения и записи. Указатель файла помещается в начало файла.
  • 'rb+' - Открывает файл в бинарном режиме для чтения и записи. Указатель файла помещается в начале файла. Это режим "по умолчанию".
  • 'w' - Открывает файл только для записи. Перезаписывает файл, если файл существует. Если файл не существует, создает новый файл для записи.
  • 'wb' - Открывает файл в бинарном режиме только для записи. Перезаписывает файл, если файл существует. Если файл не существует, создает новый файл для записи.
  • 'w+' - Открывает файл для записи и чтения. Перезаписывает существующий файл, если файл существует. Если файл не существует, создается новый файл для чтения и записи.
  • 'wb+' - Открывает файл в бинарном режиме для записи и чтения. Перезаписывает существующий файл, если файл существует. Если файл не существует, создается новый файл для чтения и записи.
  • 'a' - Открывает файл для добавления. Указатель файла находится в конце файла, если файл существует. То есть файл находится в режиме добавления. Если файл не существует, он создает новый файл для записи.
  • 'ab' - Открывает файл в бинарном режиме для добавления. Указатель файла находится в конце файла, если файл существует. То есть файл находится в режиме добавления. Если файл не существует, он создает новый файл для записи.
  • 'a+' - Открывает файл для добавления и чтения. Указатель файла находится в конце файла, если файл существует. Файл открывается в режиме добавления. Если файл не существует, он создает новый файл для чтения и записи.
  • 'ab+' - Открывает файл в бинарном режиме для добавления и чтения. Указатель файла находится в конце файла, если файл существует. Файл открывается в режиме добавления. Если файл не существует, он создает новый файл для чтения и записи.

Python различает двоичный и текстовый ввод/вывод. Файлы, открытые в двоичном режиме, возвращают содержимое в виде bytes объектов без какого-либо декодирования. В текстовом режиме (по умолчанию или когда 't' включен в аргумент mode ) содержимое файла возвращается как строка байтов, которые были сначала декодированы с использованием кодировки, используемой системой по умолчанию или с использованием переданного аргумента encoding .

Аргумент buffering - необязательное целое число, используемое для установки политики буферизации.

  • 0 - отключить буферизацию, только для бинарного режима;
  • 1 - построчная буферизация, только для текстового режима;
  • int число > 1 - размер буфера в байтах.
  • -1 - по умолчанию.

У текстовых файлов, если buffering не задан, используется построчная буферизаця. Двоичные файлы буферизируются кусками фиксированного размера. Этот размер определяется эвристикой, пытающейся определить размер блока устройства, на котором находится файл, в случае неудачи использует io.DEFAULT_BUFFER_SIZE . Для многих систем буфер равен 4096 или 8192 байт.

Аргумент encoding - это имя кодировки, используемой для декодирования или кодирования файла. Это аргумент следует использовать только в текстовом режиме. Кодировка по умолчанию зависит от платформы, но может использоваться любая кодировка текста, поддерживаемая Python.

Аргумент error является необязательным и указывает как должны обрабатываться ошибки кодирования и декодирования. Следует использовать только для текстовых файлов.

Доступны стандартные обработчики ошибок:

  • 'strict' - бросает исключение ValueError , если есть ошибка кодирования. Значение по умолчанию None имеет тот же эффект.
  • 'ignore' - игнорирует ошибки. Обратите внимание, что игнорирование ошибок кодирования может привести к потере данных.
  • 'replace' - вставляет символ ? на место непрочитанных символов, ввиду их отсутствия в используемой кодировке.
  • 'surrogateescape' - любые некорректные байты будут представлены как символы Юникода в диапазоне от U+DC80 до U+DCFF . Эти символы, при обратной операции кодирования будут возвращаться в те же байты. Полезно для обработки файлов в неизвестной кодировке.
  • 'xmlcharrefreplace' - поддерживается только при записи в файл. Символы, не поддерживаемые кодировкой, заменяются соответствующей ссылкой на символ XML.
  • 'backslashreplace' - заменяет искаженные данные на escape-последовательности Python с обратной косой чертой.
  • 'namereplace' - поддерживается только при записи, заменяет не поддерживаемые символы на \N escape-последовательности.

Аргумент newline контролирует работу режима новой строки. Работает только с текстовым режимом. Допустимые аргументы: None , '' , '\n' , '\r' и '\r\n' .

Это работает следующим образом:

  • Чтение файла:
    • если аргумент newline=None или не указан, то символами окончания строк '\n' , '\r' или '\r\n' на выходе преобразуются в разделитель строки '\n' .
    • если newline='' , то получим результат с вырезанными символами окончания строк '\n' , '\r' или '\r\n' , то есть файл прочитается как одна большая строка.
    • если newline='\n' , то в результате чтения функция open() уберет только символ \n из результата, если newline='\r' , то только \r , если newline='\r\n' , то только сочетание '\r\n' не будет учитываться.
    • если аргумент newline=None или не указан, то символы окончания строк \n будут переведены в разделители строк, которые система использует по умолчанию;
    • если newline='' или newline='\n' , то символы окончания строк \n переводится в разделители строк не будут. В файл запишется одна большая строка.
    • если newline='\r' , то в результате записи функция open() сохранит значение \r в качестве разделителя строк, если newline='\r\n' , то запишется сочетание '\r\n' .

    Аргумент closefd по умолчанию True . Если аргумент closefd=False и вместо имени файла был задан его дескриптор, то при закрытии файла функцией open() , базовый дескриптор файла будет оставаться открытым. Если задано имя файла, closefd должно быть True (по умолчанию), иначе возникнет ошибка.

    Необязательный аргумент opener (по умолчанию None ), пользовательский объект поддерживающий вызов, который следует использовать для открытия файла. Этот объект получая на входе file и flags , должен возвращать открытый дескриптор файла.

    Дополнительно смотрите функцию os.open() , которая открывает файл и возвращает его файловый дескриптор. Вновь созданный дескриптор не наследуется .

    В следующем примере используется параметр dir_fd функции os.open() , чтобы открыть файл относительно данного каталога:

    >>> import os >>> dir_fd = os.open('/some/dir', os.O_RDONLY) >>> def opener(path, flags): . return os.open(path, flags, dir_fd=dir_fd) . >>> with open('test.txt', 'w', opener=opener) as f: . print('This will be written to /some/dir/test.txt', file=f) . >>> os.close(dir_fd) # не забывайте закрыть файловый дескриптор 

    Тип файлового объекта, возвращаемого функцией open() , зависит от режима. Когда используется open() , чтобы открыть файл в текстовом режиме 'w' , 'r' , 'wt' , 'rt' и т. д., она возвращает подкласс io.TextIOBase , в частности io.TextIOWrapper . При использовании для открытия файла в двоичном режиме с буферизацией возвращаемый класс является подклассом io.BufferedIOBase .

    Итоговый класс меняется в зависимости от операции:

    • в режиме чтения двоичных файлов он возвращает io.BufferedReader ;
    • в двоичном режиме записи и в двоичном режиме добавления он возвращает io.BufferedWriter ;
    • в режиме чтения/записи - io.BufferedRandom .

    Когда отключена буферизация, исходный поток возвращает подклассы io.RawIOBase , io.FileIO .

    Примеры чтения из файла и записи в файл.

    Чтение и вывод на печать сразу всего файла:

    f = open('demofile.txt', 'r') print(f.read()) f.close() # не забывайте закрыть файл 

    Чтение всего файла и вывод на печать построчно:

    f = open('demofile.txt', 'r') for line in f: print(line) f.close() # не забывайте закрыть файл 

    Создадим файл newfile.txt и запишем в него строку. Если файл с таким именем уже существует, то данные внутри файла сотрутся.

    f = open('newfile.txt', 'w') f.write('Это единственная строка в файле\n') f.close() # не забывайте закрыть файл 

    Использование менеджера контекста для чтения/записи в файл.

    Открываем файл на запись с помощью менеджера контекста и пишем данные в конец файла.

    with open('demofile.txt', 'a') as f: f.write('Привет Мир\n') # здесь закрывать файл не надо, менеджер контекста сделает это сам. 
    • ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
    • Функция abs(), абсолютное значение числа
    • Функция all(), все элементы True
    • Функция any(), хотя бы один элемент True
    • Функция ascii(), преобразует строку в ASCII
    • Функция bin(), число в двоичную строку
    • Класс bool(), логическое значение объекта
    • Функция breakpoint(), отладчик кода
    • Класс bytearray(), преобразует в массив байтов
    • Класс bytes(), преобразует в строку байтов
    • Функция callable(), проверяет можно ли вызвать объект
    • Функция chr(), число в символ Юникода
    • Класс classmethod, делает функцию методом класса
    • Функция compile() компилирует блок кода Python
    • Класс complex(), преобразует в комплексное число
    • Функция delattr(), удаляет атрибут объекта
    • Класс dict() создает словарь
    • Функция dir(), все атрибуты объекта
    • Функция divmod(), делит числа с остатком
    • Функция enumerate(), счетчик элементов последовательности
    • Функция eval(), выполняет строку-выражение с кодом
    • Функция exec(), выполняет блок кода
    • Функция filter(), фильтрует список по условию
    • Класс float(), преобразует в вещественное число
    • Функция format(), форматирует значение переменной
    • Класс frozenset(), преобразует в неизменяемое множество
    • Функция getattr(), значение атрибута по имени
    • Функция globals(), переменные глобальной области
    • Функция hasattr(), наличие атрибута объекта
    • Функция hash(), хэш-значение объекта
    • Функция help(), справка по любому объекту
    • Функция hex(), число в шестнадцатеричную строку
    • Функция id(), идентификатор объекта
    • Функция input(), ввод данных с клавиатуры
    • Класс int(), преобразует в тип int
    • Функция isinstance(), принадлежность экземпляра к классу
    • Функция issubclass(), проверяет наследование класса
    • Функция iter(), создает итератор
    • Функция len(), количество элементов объекта
    • Класс list(), преобразовывает в список
    • Функция locals(), переменные локальной области
    • Функция map(), обработка последовательности без цикла
    • Функция max(), максимальное значение элемента
    • Класс memoryview(), ссылка на буфер обмена
    • Функция min(), минимальное значение элемента
    • Функция next(), следующий элемент итератора
    • Класс object(), возвращает безликий объект
    • Функция oct(), число в восьмеричную строку
    • Функция open(), открывает файл на чтение/запись
    • Функция ord(), число символа Unicode
    • Функция pow(), возводит число в степень
    • Функция print(), печатает объект
    • Класс property(), метод класса как свойство
    • Класс range(), генерирует арифметические последовательности
    • Функция repr(), описание объекта
    • Функция reversed(), разворачивает последовательность
    • Функция round(), округляет число
    • Класс set(), создает или преобразовывает в множество
    • Функция setattr(), создает атрибут объекта
    • Класс slice(), шаблон среза
    • Функция sorted(), выполняет сортировку
    • Декоратор staticmethod(), метод класса в статический метод
    • Класс str(), преобразует объект в строку
    • Функция sum(), сумма последовательности
    • Функция super(), доступ к унаследованным методам
    • Класс tuple(), создает или преобразует в кортеж
    • Класс type(), возвращает тип объекта
    • Функция vars(), словарь переменных объекта
    • Функция zip(), объединить элементы в список кортежей
    • Функция __import__(), находит и импортирует модуль
    • Функция aiter(), создает асинхронный итератор
    • Функция anext(), следующий элемент асинхронного итератора

    Основы работы с файлами в Python

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

    Михаил Свинцов
    автор курса «Full-stack веб-разработчик на Python»

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

    Встроенные средства Python

    Основа для работы с файлами — built-in функция open()

    open(file, mode="rt") 

    Эта функция имеет два аргумента. Аргумент file принимает строку, в которой содержится путь к файлу. Второй аргумент, mode , позволяет указать режим, в котором необходимо работать с файлом. По умолчанию этот аргумент принимает значение «rt», с которым, и с некоторыми другими, можно ознакомиться в таблице ниже

    Эти режимы могут быть скомбинированы. Например, «rb» открывает двоичный файл для чтения. Комбинируя «r+» или «w+» можно добиться открытия файла в режиме и чтения, и записи одновременно с одним отличием — первый режим вызовет исключение, если файла не существует, а работа во втором режиме в таком случае создаст его.

    Начать саму работу с файлом можно с помощью объекта класса io.TextIOWrapper , который возвращается функцией open() . У этого объекта есть несколько атрибутов, через которые можно получить информацию

    • name — название файла;
    • mode — режим, в котором этот файл открыт;
    • closed — возвращает True , если файл был закрыт.

    По завершении работы с файлом его необходимо закрыть при помощи метода close()

    f = open("examp.le", "w") // работа с файлом f.close() 

    Однако более pythonic way стиль работы с файлом встроенными средствами заключается в использовании конструкции with .. as .. , которая работает как менеджер создания контекста. Написанный выше пример можно переписать с ее помощью

    with open("examp.le", "w") as f: // работа с файлом 

    Главное отличие заключается в том, что python самостоятельно закрывает файл, и разработчику нет необходимости помнить об этом. И бонусом к этому не будут вызваны исключения при открытии файла (например, если файл не существует).

    Чтение из файла

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

    Работа со строками в Python. Готовимся к собеседованию: вспоминаем азы

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

    with open("examp.le", "r") as f: text = f.read() 

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

    with open("examp.le", "r") as f: part = f.read(16) 

    При этом будут получены только первые 16 символов текста. Важно понимать, что при применении этой функции несколько раз подряд будет считываться часть за частью этого текста — виртуальный курсор будет сдвигаться на считанную часть текста. Его можно сдвинуть на определенную позицию, при необходимости воспользовавшись методом seek() .

    with open("examp.le", "r") as f: # 'Hello, world!' first_part = f.read(8) # 'Hello, w' f.seek(4) second_part = f.read(8) # 'o, world' 

    Другой способ заключается в считывании файла построчно. Метод readline() считывает строку и, также как и с методом read() , сдвигает курсор — только теперь уже на целую строку. Применение этого метода несколько раз будет приводить к считыванию нескольких строк. Схожий с этим способом, другой метод позволяет прочитать файл целиком, но по строкам, записав их в список. Этот список можно использовать, например, в качестве итерируемого объекта в цикле.

    with open("examp.le", "r") as f: for line in f.readlines(): print(line) 

    Однако и здесь существует более pythonic way. Он заключается в том, что сам объект io.TextIOWrapper имеет итератор, возвращающий строку за строкой. Благодаря этому нет необходимости считывать файл целиком, сохраняя его в список, а можно динамически по строкам считывать файл. И делать это лаконично.

    with open("examp.le", "r") as f: for line in f: print(line) 

    Запись в файл

    Функциональность внесения данных в файл не зависит от режима — добавление данных или перезаписывание файла. В выполнении этой операции также существует несколько подходов.

    Самый простой и логичный — использование функции write()

    with open("examp.le", "w") as f: f.write(some_string_data) 

    Важно, что в качестве аргумента функции могут быть переданы только строки. Если необходимо записать другого рода информацию, то ее необходимо явно привести к строковому типу, используя методы __str__(self) для объектов или форматированные строки.

    Есть возможность записать в файл большой объем данных, если он может быть представлен в виде списка строк.

    with open("examp.le", "w") as f: f.writelines(list_of_strings) 

    Здесь есть еще один нюанс, связанный с тем, что функции write() и writelines() автоматически не ставят символ переноса строки, и это разработчику нужно контролировать самостоятельно.

    Существует еще один, менее известный, способ, но, возможно, самый удобный из представленных. И как бы не было странно, он заключается в использовании функции print() . Сначала это утверждение может показаться странным, потому что общеизвестно, что с помощью нее происходит вывод в консоль. И это правда. Но если передать в необязательный аргумент file объект типа io.TextIOWrapper , каким и является объект файла, с которым мы работаем, то поток вывода функции print() перенаправляется из консоли в файл.

    with open("examp.le", "w") as f: print(some_data, file=f) 

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

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

    Следите за новыми постами по любимым темам

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *