При помощи какого оператора текстовый файл открывается для перезаписи
Перейти к содержимому

При помощи какого оператора текстовый файл открывается для перезаписи

  • автор:

Функция open() в Python. Чтение и запись файлов

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

Бывают еще байтовые (бинарные) файлы, которые рассматриваются как потоки байтов. По байтам считываются, например, файлы изображений. Работа с бинарными файлами несколько сложнее. Нередко их обрабатывают с помощью специальных модулей Python (pickle, struct).

Функция open

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

Обычно используются режимы чтения ( ‘r’ ) и записи ( ‘w’ ). Если файл открыт в режиме чтения, то запись в него невозможна. Можно только считывать данные. Если файл открыт в режиме записи, то в него можно только записывать данные, считывать нельзя.

Если файл открывается в режиме ‘w’ , то все данные, которые в нем были до этого, стираются. Файл становится пустым. Если не надо удалять существующие в файле данные, тогда следует использовать вместо режима записи, режим дозаписи ( ‘a’ ).

Если файл отсутствует, то открытие его в режиме ‘w’ создаст новый файл. Бывают ситуации, когда надо гарантировано создать новый файл, избежав случайной перезаписи данных существующего. В этом случае вместо режима ‘w’ используется режим ‘x’ . В нем всегда создается новый файл для записи. Если указано имя существующего файла, то будет выброшено исключение. Потери данных в уже имеющемся файле не произойдет.

Если при вызове open() второй аргумент не указан, то файл открывается в режиме чтения как текстовый файл. Чтобы открыть файл как байтовый, дополнительно к букве режима чтения/записи добавляется символ ‘b’ . Буква ‘t’ обозначает текстовый файл. Поскольку это тип файла по умолчанию, то обычно ее не указывают.

Нельзя указывать только тип файла, то есть open(«имя_файла», ‘b’) есть ошибка, даже если файл открывается на чтение. Правильно – open(«имя_файла», ‘rb’) . Только текстовые файлы мы можем открыть командой open(«имя_файла») , потому что и ‘r’ и ‘t’ подразумеваются по-умолчанию.

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

Чтение файла

С помощью файлового метода read() можно прочитать файл целиком или только определенное количество байт. Пусть у нас имеется файл data.txt с таким содержимым:

one - 1 - I two - 2 - II three - 3 - III four - 4 - IV five - 5 - V

Откроем его и почитаем:

>>> f1 = open(‘data.txt’) >>> f1.read(10) ‘one — 1 — ‘ >>> f1.read() ‘I\ntwo — 2 — II\nthree — 3 — III\nfour — 4 — IV\nfive — 5 — V\n’ >>> f1.read() » >>> type(f1.read())

Сначала считываются первые десять символов. Последующий вызов read() считывает весь оставшийся текст. После этого объект файлового типа f1 становится пустым.

Заметим, что метод read() возвращает строку.

Для того чтобы читать файл построчно, существует метод readline() :

>>> f1 = open('data.txt') >>> f1.readline() 'one - 1 - I\n' >>> f1.readline() 'two - 2 - II\n' >>> f1.readline() 'three - 3 — III\n' 

Метод readlines() считывает сразу все строки и создает список:

>>> f1 = open('data.txt') >>> f1.readlines() ['one - 1 - I\n', 'two - 2 - II\n', 'three - 3 - III\n', 'four - 4 - IV\n', 'five - 5 - V\n'] 

Объект файлового типа относится к итераторам. Из таких объектов происходит последовательное извлечение элементов. Элементами в данном случае являются строки-линии файла. Поэтому считывать данные из файла можно сразу в цикле без использования методов чтения:

>>> for i in open('data.txt'): . print(i) . one - 1 - I two - 2 - II three - 3 - III four - 4 - IV five - 5 - V >>> 

Здесь выводятся лишние пустые строки, потому что функция print() преобразует ‘\n’ в переход на новую строку. К этому добавляет свой переход на новую строку. Создадим список строк файла без ‘\n’ :

>>> nums = [] >>> for i in open('data.txt'): . nums.append(i[:-1]) . >>> nums ['one - 1 - I', 'two - 2 - II', 'three - 3 - III', 'four - 4 - IV', 'five - 5 - V'] 

Переменной i присваивается очередная строка файла. Мы берем ее срез от начала до последнего символа, не включая его. Следует иметь в виду, что ‘\n’ это один символ, а не два.

Запись в файл

Запись в файл выполняется с помощью методов write() и writelines() . Во второй можно передать структуру данных:

>>> l = ['three', 'four'] >>> f2 = open('newdata.txt', 'w') >>> f2.write('one') 3 >>> f2.write(' two') 4 >>> f2.writelines(l) 

Метод write() возвращает количество записанных символов.

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

После того как работа с файлом закончена, важно не забывать его закрыть, чтобы освободить место в памяти. Делается это с помощью файлового метода close() . Свойство файлового объекта closed позволяет проверить закрыт ли файл.

>>> f1.close() >>> f1.closed True >>> f2.closed False 

Если файл открывается в заголовке цикла ( for i in open(‘fname’) ), он автоматически не закрывается при завершении работы цикла, а остается открытым на неопределенное количество времени. Поэтому в больших программах лучше так не делать. Если файл открывается для одномоментного чтения или записи, и вы не хотите захламлять код строчками кода его открытия и закрытия, то следует использовать оператор with . Он отслеживает, чтобы при выходе из его тела файл был закрыт. Пример использования:

>>> with open('test.txt') as f: . for line in f: . print(line, end='') . one two three four 

Практическая работа

  1. Создайте файл data.txt по образцу урока. Напишите программу, которая открывает этот файл на чтение, построчно считывает из него данные и записывает строки в другой файл ( dataRu.txt ), заменяя английские числительные русскими, которые содержатся в списке ( [«один», «два», «три», «четыре», «пять»] ), определенном до открытия файлов.
  2. Создайте файл nums.txt , содержащий несколько чисел, записанных через пробел. Напишите программу, которая подсчитывает и выводит на экран общую сумму чисел, хранящихся в этом файле.

Примеры решения и дополнительные уроки в pdf-версии курса

X Скрыть Наверх

Python. Введение в программирование

Типизированные файлы в Паскаль

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

При описании типизированных файлов указывается тип его компонентов, число которых (длина файла) не фиксируется:

var имя_файла: file of тип_компонентов

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

var FileInt: file of Integer;

В этом описании указано, что элементами файла являются данные типа Integer , занимающие 2 байта (или 4). При этом отпадает необходимость в специальном разделении элементов файла, как это делалось в текстовых файлах. Также возможен произвольный доступ к элементам данных (этим типизированный файл несколько напоминает одномерный массив).

Чтобы можно было работать с типизированным файлом, необходимо, как и для текстовых файлов, сначала связать имя файловой переменной с внешним именем файла (оператор assign ). Затем нужно открыть его (используются операторы reset или rewrite ).

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

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

Чтение из типизированного файла производится оператором read (но не readln ), а запись в него — оператором write (но не writeln ). Однако следует помнить, что в списке вывода оператора write могут быть только переменные. Типы элементов файла и типы переменных в списках ввода-вывода должны быть согласуемы по присваиванию. Элементами типизированных файлов могут быть числовые, символьные, булевы, строковые значения, массивы, записи, но не файлы или структуры с файловыми элементами.

Узнать количество элементов типизированного файла (размер файла) можно с помощью функции FileSize , для которой используется следующий синтаксис:

Например, если переменная k имеет тип LongInt , а f – файловая переменная типизированного файла, то выражение k := FileSize(f) , записывает в переменную k размер файла f .

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

FilePos(имя_файла)

Текущим положением указателя можно управлять, для чего служит процедура Seek , которая использует следующий синтаксис:

Seek(имя_файла, номер_элемента)

Второй параметр (тип LongInt ) задает номер элемента (отсчет от 0), на который должен переместиться указатель файла. Рассмотрим несколько примеров.

Перейти к пятому (фактически шестому) элементу файла f :

Seek(f, 5);

Перейти к предыдущему элементу:

Seek(f, FilePos(f)-1);

Перейти в конец файла:

Seek(f, FileSize(f)-1);

Как и для текстовых файлов, можно использовать функцию Eof(имя_файла) , которая возвращает значение True , если текущий указатель расположен на признаке конца файла (то есть при выполнения равенства FilePos(имя_файла) = FileSize(имя_файла) ).

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

Текстовые файлы могут быть созданы текстовым редактором. Однако типизированные файлы создаются в результате работы какой-либо программы.

Пример записи данных в типизированный файл:

type t_subscriber = record surname: string[20]; tel: LongInt; end; var subscriber: t_subscriber; f: file of t_subscriber; i: Integer; begin Assign(f,'notebook.dat'); Rewrite(f); for i:=1 to 5 do begin with subscriber do begin Write('Surname: '); ReadLn(surname); Write('Phone: '); ReadLn(tel); end; Write(f, subscriber); end; Close(f); end.

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

type t_subscriber = record surname: string[20]; tel: LongInt; end; var subscriber: t_subscriber; f: file of t_subscriber; s: string[7]; begin Assign(f,'notebook.dat'); Reset(f); while not Eof(f) do begin Read(f, subscriber); with subscriber do begin str(tel,s); if Copy(s,1,2) = '33' then tel := tel+4000000; end; Seek(f,FilePos(f)-1); // возврат указателя назад Write(f,subscriber); end; Close(f); end. 

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

При помощи какого оператора текстовый файл открывается для перезаписи

Для работы с файлами в стандартной библиотеке определен заголовочный файл fstream , который определяет базовые типы для чтения и записи файлов. В частности, это:

  • ifstream : для чтения с файла
  • ofstream : для записи в файл
  • fstream : совмещает запись и чтение

Для работы с данными типа wchar_t для этих потоков определены двойники:

  • wifstream
  • wofstream
  • wfstream

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

При операциях с файлом вначале необходимо открыть файл с помощью функции open() . Данная функция имеет две версии:

  • open(путь)
  • open(путь, режим)

Для открытия файла в функцию необходимо передать путь к файлу в виде строки. И также можно указать режим открытия. Список доступных режимов открытия файла:

  • ios::in : файл открывается для ввода (чтения). Может быть установлен только для объекта ifstream или fstream
  • ios::out : файл открывается для вывода (записи). При этом старые данные удаляются. Может быть установлен только для объекта ofstream или fstream
  • ios::app : файл открывается для дозаписи. Старые данные не удаляются.
  • ios::ate : после открытия файла перемещает указатель в конец файла
  • ios::trunc : файл усекается при открытии. Может быть установлен, если также установлен режим out
  • ios::binary : файл открывается в бинарном режиме

Если при открытии режим не указан, то по умолчанию для объектов ofstream применяется режим ios::out , а для объектов ifstream — режим ios::in . Для объектов fstream совмещаются режимы ios::out и ios::in .

std::ofstream out; // поток для записи out.open("hello1.txt"); // окрываем файл для записи std::ofstream out2; out2.open("hello2.txt", std::ios::app); // окрываем файл для дозаписи std::ofstream out3; out2.open("hello3.txt", std::ios::out | std::ios::trunc); // установка нескольких режимов std::ifstream in; // поток для чтения in.open("hello4.txt"); // окрываем файл для чтения std::fstream fs; // поток для чтения-записи fs.open("hello5.txt"); // окрываем файл для чтения-записи

Однако в принципе необязательно использовать функцию open для открытия файла. В качестве альтернативы можно также использовать конструктор объектов-потоков и передавать в них путь к файлу и режим открытия:

fstream(путь) fstream(путь, режим)

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

std::ofstream out("hello.txt"); std::ifstream in("hello.txt"); std::fstream fs("hello.txt", std::ios::app);

В данном случае предполагается, что файл «hello.txt» располагается в той же папке, где и файл программы.

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

В процессе работы мы можем проверить, окрыт ли файл с помощью функции is_open() . Если файл открыт, то она возвращает true:

std::ifstream in; // поток для чтения in.open(«hello.txt»); // окрываем файл для чтения // если файл открыт if (in.is_open())

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

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

#include #include int main() < std::ofstream out; // поток для записи out.open("hello.txt"); // окрываем файл для записи out.close(); // закрываем файл std::ifstream in; // поток для чтения in.open("hello.txt"); // окрываем файл для чтения in.close(); // закрываем файл std::fstream fs; // поток для чтения-записи fs.open("hello.txt"); // окрываем файл для чтения-записи fs.close(); // закрываем файл >

Ввод-вывод, оператор присваивания, арифметические операции

Теоретический материал: файловый ввод-вывод (Паскаль)

Тeкстовые файлы, их описание и основные отличия от типизированных файлов

Наряду с типизированными файлами Pascal имеет средства взаимодействия с файлами несколько иной структуры — так называемыми текстовыми файлами. Введение текстовых файлов несколько нарушает стройность языка, однако позволяет использовать Pascal при программировании широкого класса задач, имеющих нечисловой характер и связанных с обработкой текстовой информации. Во многих версиях языка допускается хранение файлов на диске как символьных данных. При считывании файла в оперативную память машины символы файла преобразуются в тот тип данных, который объявлен в программе. Файлы символьных данных называются текстовыми файлами. Структура текстовых файлов отличается от структуры обычных файлов (которые представляют собой линейную последовательность элементов одного типа) тем, что содержимое текстового файла рассматривается как последовательность строк переменной длины, разделённых специальной комбинацией кодов, называемой «конец строки». Как правило, эта комбинация строится из управляющего кода «возврата каретки» (CR, Carriage Return, символ #13), за которым, возможно, следует управляющий код «перевод строки» (LF, Line Feed, символ #10). При вводе c клавиатуры признаком конца строки считается нажатие клавиши Enter. Текстовый файл завершается специальным кодом «конец файла» (символ #26). В большинстве случаев знание конкретной кодировки управляющих символов не обязательно ввиду наличия файловых операций, автоматически учитывающих эти символы. Таким образом, текстовый файл структурно несколько похож на «файл из байтов» (file of byte) с той разницей, что в нем, помимо содержательной информации, встречаются символы специального назначения. Его можно схематически представить в следующем виде: . . . . . . . . . . . . . .#13#10
. . . . . . . . . . . . . . . . . . . .#13#10
. . . . . . . . . . . . . . . . .#13#10
. . . . . . . . . . . .#13#10
. . . . . . . . . . . . . . . . . . . . . . . . . .#13#10
#26 Описанная структура текстовых файлов хорошо согласуется с интуитивно понятным построением текстовой информации и полностью совпадает со стандартной структурой текстов, используемой во многих текстовых редакторах, понимаемой компиляторами с языков программирования и т.д. С каждым файлом на диске в программе должна быть связана некоторая файловая переменная, которая описывается в соответствии с типом файла. Текстовому файлу в Pascal-программе соответствует переменная, которая должна быть описана с указанием стандартного типа text:

Var
TextFile : text;

Примечание. Слово text не является зарезервированным словом, а считается идентификатором стандартного типа, наряду с идентификаторами integer, real и т.д. После описания переменной типа text ее надо связать с конкретным файлом процедурой assign. Вся последующая работа с файлом будет вестись через файловую переменную. Далее доступ к файлу требуется открыть на чтение или на запись, для этого существуют процедуры reset и rewrite. К примеру, пусть на диске создан текстовый файл text.txt. Для Turbo Pascal описание и связывание файловой переменной f с файлом text.txt, будет выглядеть так :

Var
f: text;
Begin
assign(f, ‘d:\tp7\bin\text.txt’);
reset(f); . . .
End.

Процедура assign( , ) — связывает файл на диске с файловой переменной типа Text. Примечание. Процедура assign не должна использоваться для открытого файла. Если при вызове процедуры assign в качестве имени файла задается пустая строка: assign(f,»), то после обращения к reset(f) переменная f будет связана со стандартным файлом ввода, а после обращения к rewrite(f) – со стандартным файлом вывода. Процедура reset( ) — открывает файл на чтение. Ввод-вывод для текстовых файлов подчиняется тем же правилам, что и для типизированных файлов; однако имеется несколько важных особенностей. Во-первых, для одного текстового файла нельзя одновременно производить операции и ввода, и вывода. Это означает, что после открытия текстового файла процедурой reset возможно только чтение информации из файла, а после процедуры rewrite — только запись в файл. Во-вторых, обмены с текстовыми файлами всегда являются строго последовательными, то есть после чтения из файла элемента с порядковым номером N следующая операция чтения даст элемент с номером N+1. Иными словами, прямой доступ к любому элементу текстового файла невозможен; для текстовых файлов не допускаются вызовы Seek, FilePos, FileSize. Под чтением файла понимают ввод данных из внешнего файла, находящегося на диске, в оперативную память компьютера. Данные файла становятся доступными программе. Внешний файл, из которого читаются данные, часто называют входным файлом. Базовой техникой обменов с текстовыми файлами является посимвольный ввод-вывод. При этом производится чтение или запись всех символов, как информационных, так и специальных. Покажем простую программу, выполняющую чтение некоторого текста. Эта программа выводит на экран последовательность кодов символов, составляющих файл text.txt.

Program TextFile1;
Var
f : text;
S : char;
Begin
assign(f, ‘text.txt’);
reset(f);
while not Eof(f) do
begin
read(f, S);
writeln(S:2, ord(S):4);
end;
close(f);
readln
End.

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

Program TextFile2;
Var
f : text;
Put : string;
a : integer;
Begin
Put := ‘D:\TP7\BIN\Primer2’;
assign(f, Put);
reset(f);
while not Eof(f) do
begin
readln(f, a);
if not odd(a)
then
writeln(a);
end;
close(f);
readln
End.
  • значения целого типа;
  • значения вещественного типа;
  • значения булевского типа.

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

Program TextFile3;
Var
f : text;
V : real;
i : word;
Put : string;
Begin
Put := ‘D:\TP7\BIN\Primer3’;
assign(f, Put);
rewrite(f);
V := 123.456;
write(f, V,#13#10);
for i := 10 to 14 do
write(f, V:i,#13#10);
close(f);
End.

Задание. Наберите программу, дополните ее выводом содержимого текстового файла на экран. Проанализируйте результаты выполнения программы.

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

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

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

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