C работа с текстовыми файлами txt. Ввод данных из файла и вывод в файл. Чтение из двоичного файла и запись в него
Для удобства обращения информация в запоминающих устройствах хранится в виде файлов.
Файл – именованная область внешней памяти, выделенная для хранения массива данных. Данные, содержащиеся в файлах, имеют самый разнообразный характер: программы на алгоритмическом или машинном языке; исходные данные для работы программ или результаты выполнения программ; произвольные тексты; графические изображения и т. п.
Каталог (папка , директория ) – именованная совокупность байтов на носителе информации, содержащая название подкаталогов и файлов, используется в файловой системе для упрощения организации файлов.
Файловой системой называется функциональная часть операционной системы, обеспечивающая выполнение операций над файлами. Примерами файловых систем являются FAT (FAT – File Allocation Table, таблица размещения файлов), NTFS, UDF (используется на компакт-дисках).
Существуют три основные версии FAT: FAT12, FAT16 и FAT32. Они отличаются разрядностью записей в дисковой структуре, т.е. количеством бит, отведённых для хранения номера кластера. FAT12 применяется в основном для дискет (до 4 кбайт), FAT16 – для дисков малого объёма, FAT32 – для FLASH-накопителей большой емкости (до 32 Гбайт).
Рассмотрим структуру файловой системы на примере FAT32.
Файловая структура FAT32
Устройства внешней памяти в системе FAT32 имеют не байтовую, а блочную адресацию. Запись информации в устройство внешней памяти осуществляется блоками или секторами.
Сектор – минимальная адресуемая единица хранения информации на внешних запоминающих устройствах. Как правило, размер сектора фиксирован и составляет 512 байт. Для увеличения адресного пространства устройств внешней памяти сектора объединяют в группы, называемые кластерами.
Кластер
– объединение нескольких секторов, которое может рассматриваться как самостоятельная единица, обладающая определёнными свойствами. Основным свойством кластера является его размер, измеряемый в количестве секторов или количестве байт.
Файловая система FAT32 имеет следующую структуру.
Нумерация кластеров, используемых для записи файлов, ведется с 2. Как правило, кластер №2 используется корневым каталогом, а начиная с кластера №3 хранится массив данных. Сектора, используемые для хранения информации, представленной выше корневого каталога, в кластеры не объединяются.
Минимальный размер файла, занимаемый на диске, соответствует 1 кластеру.
Загрузочный сектор начинается следующей информацией:
- EB 58 90 – безусловный переход и сигнатура;
- 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
- 00 02 – количество байт в секторе (обычно 512);
- 1 байт – количество секторов в кластере;
- 2 байта – количество резервных секторов.
Кроме того, загрузочный сектор содержит следующую важную информацию:
- 0x10 (1 байт) – количество таблиц FAT (обычно 2);
- 0x20 (4 байта) – количество секторов на диске;
- 0x2С (4 байта) – номер кластера корневого каталога;
- 0x47 (11 байт) – метка тома;
- 0x1FE (2 байта) – сигнатура загрузочного сектора (55 AA ).
Сектор информации файловой системы содержит:
- 0x00 (4 байта) – сигнатура (52 52 61 41 );
- 0x1E4 (4 байта) – сигнатура (72 72 41 61 );
- 0x1E8 (4 байта) – количество свободных кластеров, -1 если не известно;
- 0x1EС (4 байта) – номер последнего записанного кластера;
- 0x1FE (2 байта) – сигнатура (55 AA ).
Таблица FAT содержит информацию о состоянии каждого кластера на диске. Младшие 2 байт таблицы FAT хранят F8 FF FF 0F FF FF FF FF (что соответствует состоянию кластеров 0 и 1, физически отсутствующих). Далее состояние каждого кластера содержит номер кластера, в котором продолжается текущий файл или следующую информацию:
- 00 00 00 00 – кластер свободен;
- FF FF FF 0F – конец текущего файла.
- 8 байт – имя файла;
- 3 байта – расширение файла;
Корневой каталог содержит набор 32-битных записей информации о каждом файле, содержащих следующую информацию:
В случае работы с длинными именами файлов (включая русские имена) кодировка имени файла производится в системе кодировки UTF-16. При этого для кодирования каждого символа отводится 2 байта. При этом имя файла записывается в виде следующей структуры:
- 1 байт последовательности;
- 10 байт содержат младшие 5 символов имени файла;
- 1 байт атрибут;
- 1 байт резервный;
- 1 байт – контрольная сумма имени DOS;
- 12 байт содержат младшие 3 символа имени файла;
- 2 байта – номер первого кластера;
- остальные символы длинного имени.
Работа с файлами в языке Си
Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода . Выводимая информация записывается в поток, вводимая информация считывается из потока.
Когда поток открывается для ввода-вывода, он связывается со стандартной структурой типа FILE , которая определена в stdio.h . Структура FILE содержит необходимую информацию о файле.
Открытие файла осуществляется с помощью функции fopen() , которая возвращает указатель на структуру типа FILE , который можно использовать для последующих операций с файлом.
FILE *fopen(name, type);
name – имя открываемого файла (включая путь),
type — указатель на строку символов, определяющих способ доступа к файлу:
- "r" - открыть файл для чтения (файл должен существовать);
- "w" - открыть пустой файл для записи; если файл существует, то его содержимое теряется;
- "a" - открыть файл для записи в конец (для добавления); файл создается, если он не существует;
- "r+" - открыть файл для чтения и записи (файл должен существовать);
- "w+" - открыть пустой файл для чтения и записи; если файл существует, то его содержимое теряется;
- "a+" - открыть файл для чтения и дополнения, если файл не существует, то он создаётся.
Возвращаемое значение — указатель на открытый поток. Если обнаружена ошибка, то возвращается значение NULL .
Функция fclose() закрывает поток или потоки, связанные с открытыми при помощи функции fopen() файлами. Закрываемый поток определяется аргументом функции fclose() .
Возвращаемое значение: значение 0, если поток успешно закрыт; константа EOF
, если произошла ошибка.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include
int
main() {
FILE *fp;
char
name = "my.txt"
;
if
((fp = fopen(name, "r"
)) == NULL
)
{
printf("Не удалось открыть файл"
);
getchar();
return
0;
}
// открыть файл удалось
... // требуемые действия над данными
fclose(fp);
getchar();
return
0;
}
Чтение символа из файла
:
char
fgetc(поток);
Аргументом функции является указатель на поток типа FILE . Функция возвращает код считанного символа. Если достигнут конец файла или возникла ошибка, возвращается константа EOF .
Запись символа в файл
:
fputc(символ,поток);
Аргументами функции являются символ и указатель на поток типа FILE . Функция возвращает код считанного символа.
Функции fscanf()
и fprintf()
аналогичны функциям scanf()
и printf()
, но работают с файлами данных, и имеют первый аргумент - указатель на файл.
fscanf(поток, "ФорматВвода"
, аргументы);
Большинство компьютерных программ работают с файлами, и поэтому возникает необходимость создавать, удалять, записывать читать, открывать файлы. Что же такое файл? Файл – именованный набор байтов, который может быть сохранен на некотором накопителе. Ну, теперь ясно, что под файлом понимается некоторая последовательность байтов, которая имеет своё, уникальное имя, например файл.txt . В одной директории не могут находиться файлы с одинаковыми именами. Под именем файла понимается не только его название, но и расширение, например: file.txt и file.dat — разные файлы, хоть и имеют одинаковые названия. Существует такое понятие, как полное имя файлов – это полный адрес к директории файла с указанием имени файла, например: D:\docs\file.txt . Важно понимать эти базовые понятия, иначе сложно будет работать с файлами.
Для работы с файлами необходимо подключить заголовочный файл
Файловый ввод/вывод аналогичен стандартному вводу/выводу, единственное отличие – это то, что ввод/вывод выполнятся не на экран, а в файл. Если ввод/вывод на стандартные устройства выполняется с помощью объектов cin и cout , то для организации файлового ввода/вывода достаточно создать собственные объекты, которые можно использовать аналогично операторам cin и cout .
Например, необходимо создать текстовый файл и записать в него строку Работа с файлами в С++ . Для этого необходимо проделать следующие шаги:
- создать объект класса ofstream ;
- связать объект класса с файлом, в который будет производиться запись;
- записать строку в файл;
- закрыть файл.
Почему необходимо создавать объект класса ofstream , а не класса ifstream ? Потому, что нужно сделать запись в файл, а если бы нужно было считать данные из файла, то создавался бы объект класса ifstream .
// создаём объект для записи в файл ofstream /*имя объекта*/; // объект класса ofstream
Назовём объект – fout , Вот что получится:
Ofstream fout;
Для чего нам объект? Объект необходим, чтобы можно было выполнять запись в файл. Уже объект создан, но не связан с файлом, в который нужно записать строку.
Fout.open("cppstudio.txt"); // связываем объект с файлом
Через операцию точка получаем доступ к методу класса open(), в круглых скобочках которого указываем имя файла. Указанный файл будет создан в текущей директории с программой. Если файл с таким именем существует, то существующий файл будет заменен новым. Итак, файл открыт, осталось записать в него нужную строку. Делается это так:
Fout << "Работа с файлами в С++"; // запись строки в файл
Используя операцию передачи в поток совместно с объектом fout строка Работа с файлами в С++ записывается в файл. Так как больше нет необходимости изменять содержимое файла, его нужно закрыть, то есть отделить объект от файла.
Fout.close(); // закрываем файл
Итог – создан файл со строкой Работа с файлами в С++ .
Шаги 1 и 2 можно объединить, то есть в одной строке создать объект и связать его с файлом. Делается это так:
Ofstream fout("cppstudio.txt"); // создаём объект класса ofstream и связываем его с файлом cppstudio.txt
Объединим весь код и получим следующую программу.
// file.cpp: определяет точку входа для консольного приложения.
#include "stdafx.h"
#include
Осталось проверить правильность работы программы, а для этого открываем файл cppstudio.txt и смотрим его содержимое, должно быть — Работа с файлами в С++ .
- создать объект класса ifstream и связать его с файлом, из которого будет производиться считывание;
- прочитать файл;
- закрыть файл.
В программе показаны два способа чтения из файла, первый – используя операцию передачи в поток, второй – используя функцию getline() . В первом случае считывается только первое слово, а во втором случае считывается строка, длинной 50 символов. Но так как в файле осталось меньше 50 символов, то считываются символы включительно до последнего. Обратите внимание на то, что считывание во второй раз (строка 17 ) продолжилось, после первого слова, а не с начала, так как первое слово было прочитано в строке 14 . Результат работы программы показан на рисунке 1.
Работа с файлами в С++ Для продолжения нажмите любую клавишу. . .
Рисунок 1 — Работа с файлами в С++
Программа сработала правильно, но не всегда так бывает, даже в том случае, если с кодом всё впорядке. Например, в программу передано имя несуществующего файла или в имени допущена ошибка. Что тогда? В этом случае ничего не произойдёт вообще. Файл не будет найден, а значит и прочитать его не возможно. Поэтому компилятор проигнорирует строки, где выполняется работа с файлом. В результате корректно завершится работа программы, но ничего, на экране показано не будет. Казалось бы это вполне нормальная реакции на такую ситуацию. Но простому пользователю не будет понятно, в чём дело и почему на экране не появилась строка из файла. Так вот, чтобы всё было предельно понятно в С++ предусмотрена такая функция — is_open() , которая возвращает целые значения: 1 — если файл был успешно открыт, 0 — если файл открыт не был. Доработаем программу с открытием файла, таким образом, что если файл не открыт выводилось соответствующее сообщение.
// file_read.cpp: определяет точку входа для консольного приложения.
#include "stdafx.h"
#include
Результат работы программы показан на рисунке 2.
Файл не может быть открыт! Для продолжения нажмите любую клавишу. . .
Рисунок 2 — Работа с файлами в С++
Как видно из рисунка 2 программа сообщила о невозможности открыть файл. Поэтому, если программа работает с файлами, рекомендуется использовать эту функцию, is_open() , даже, если уверены, что файл существует.
Режимы открытия файлов
Режимы открытия файлов устанавливают характер использования файлов. Для установки режима в классе ios_base предусмотрены константы, которые определяют режим открытия файлов (см. Таблица 1).
Режимы открытия файлов можно устанавливать непосредственно при создании объекта или при вызове функции open() .
Ofstream fout("cppstudio.txt", ios_base::app); // открываем файл для добавления информации к концу файла fout.open("cppstudio.txt", ios_base::app); // открываем файл для добавления информации к концу файла
Режимы открытия файлов можно комбинировать с помощью поразрядной логической операции или | , например: ios_base::out | ios_base::trunc — открытие файла для записи, предварительно очистив его.
Объекты класса ofstream , при связке с файлами по умолчанию содержат режимы открытия файлов ios_base::out | ios_base::trunc . То есть файл будет создан, если не существует. Если же файл существует, то его содержимое будет удалено, а сам файл будет готов к записи. Объекты класса ifstream связываясь с файлом, имеют по умолчанию режим открытия файла ios_base::in — файл открыт только для чтения. Режим открытия файла ещё называют — флаг, для удобочитаемости в дальнейшем будем использовать именно этот термин. В таблице 1 перечислены далеко не все флаги, но для начала этих должно хватить.
Обратите внимание на то, что флаги ate и app по описанию очень похожи, они оба перемещают указатель в конец файла, но флаг app позволяет производить запись, только в конец файла, а флаг ate просто переставляет флаг в конец файла и не ограничивает места записи.
Разработаем программу, которая, используя операцию sizeof() , будет вычислять характеристики основных типов данных в С++ и записывать их в файл. Характеристики:
- число байт, отводимое под тип данных
- максимальное значение, которое может хранить определённый тип данных.
Запись в файл должна выполняться в таком формате:
/* data type byte max value bool = 1 255.00 char = 1 255.00 short int = 2 32767.00 unsigned short int = 2 65535.00 int = 4 2147483647.00 unsigned int = 4 4294967295.00 long int = 4 2147483647.00 unsigned long int = 4 4294967295.00 float = 4 2147483647.00 long float = 8 9223372036854775800.00 double = 8 9223372036854775800.00 */
Такая программа уже разрабатывалась ранее в разделе , но там вся информация о типах данных выводилась на стандартное устройство вывода, а нам необходимо программу переделать так, чтобы информация записывалась в файл. Для этого необходимо открыть файл в режиме записи, с предварительным усечением текущей информации файла (строка 14 ). Как только файл создан и успешно открыт (строки 16 — 20), вместо оператора cout , в строке 22 используем объект fout . таким образом, вместо экрана информация о типах данных запишется в файл.
// write_file.cpp: определяет точку входа для консольного приложения.
#include "stdafx.h"
#include
Нельзя не заметить, что изменения в программе минимальны, а всё благодаря тому, что стандартный ввод/вывод и файловый ввод/вывод используются абсолютно аналогично. В конце программы, в строке 45 мы явно закрыли файл, хотя это и не обязательно, но считается хорошим тоном программирования. Стоит отметить, что все функции и манипуляторы используемые для форматирования стандартного ввода/вывода актуальны и для файлового ввода/вывода. Поэтому не возникло никаких ошибок, когда оператор cout был заменён объектом fout .
Работа файлового ввода/вывода в C++ почти аналогична работе обычных (но с небольшими нюансами).
Классы файлового ввода/вывода
Есть три основных класса файлового ввода/вывода в C++ :
ofstream (является дочерним классу );
fstream (является дочерним классу iostream).
С помощью этих классов можно выполнять однонаправленный файловый ввод, однонаправленный файловый вывод и двунаправленный файловый ввод/вывод. Для их использования нужно всего лишь подключить fstream.
В отличие от потоков cout, cin, cerr и clog, которые сразу же можно использовать, файловые потоки должны быть явно установлены программистом. То есть, чтобы открыть файл для чтения и/или записи, нужно создать объект соответствующего класса файлового ввода/вывода, указав имя файла в качестве параметра. Затем, с помощью операторов вставки (<<) или извлечения (>>), можно записывать данные в файл или читать содержимое файла. После этого финал — нужно закрыть файл: явно вызвать метод close() или просто позволить файловой переменной ввода/вывода выйти из области видимости ( файлового класса ввода/вывода закроет этот файл автоматически вместо нас).
Файловый вывод
Для записи в файл используется класс ofstream . Например:
#include
#include #include #include int main () using namespace std ; // ofstream используется для записи данных в файл // Создаём файл SomeText.txt ofstream outf ("SomeText.txt" ) ; // Если мы не можем открыть этот файл для записи данных в него if (! outf ) // То выводим сообщение об ошибке и выполняем exit() cerr << << endl ; exit (1 ) ; // Записываем в файл следующие две строчки outf << "See line #1!" << endl ; outf << "See line #2!" << endl ; return 0 ; // Когда outf выйдет из области видимости, то деструктор класса ofstream автоматически закроет наш файл |
Если вы загляните в каталог вашего проекта (ПКМ по вкладке с названием вашего.cpp файла в Visual Studio > «Открыть содержащую папку» ), то увидите файл с именем SomeText.txt, в котором находятся следующие строчки:
See line #1!
See line #2!
Обратите внимание, мы также можем использовать метод put()
для записи одного символа в файл.
Файловый ввод
#include
#include #include #include #include int main () using namespace std ; // ifstream используется для чтения содержимого файла // Если мы не можем открыть этот файл для чтения его содержимого if (! inf ) // То выводим следующее сообщение об ошибке и выполняем exit() cerr << << endl ; exit (1 ) ; // Пока есть данные, которые мы можем прочитать while (inf ) // То перемещаем эти данные в строку, которую затем выводим на экран string strInput ; inf >> strInput ; cout << strInput << endl ; return 0 ; // Когда inf выйдет из области видимости, то деструктор класса ifstream автоматически закроет наш файл |
See
line
#1!
See
line
#2!
Хм, это не совсем то, что мы хотели. Как мы уже знаем из предыдущих уроков, оператор извлечения работает с «отформатированными данными», т.е. он игнорирует все пробелы, символы табуляции и символ новой строки. Чтобы прочитать всё содержимое как есть, без его разбивки на части (как в примере выше), нам нужно использовать метод getline() :
#include
#include #include #include #include int main () using namespace std ; // ifstream используется для чтения содержимого файлов ifstream inf ("SomeText.txt" ) ; // Если мы не можем открыть файл для чтения его содержимого if (! inf ) // То выводим следующее сообщение об ошибке и выполняем exit() cerr << "Uh oh, SomeText.txt could not be opened for reading!" << endl ; exit (1 ) ; while (inf ) string strInput ; getline (inf , strInput ) ; cout << strInput << endl ; return 0 ; // Когда inf выйдет из области видимости, то деструктор класса ifstream автоматически закроет наш файл |
Результат выполнения программы выше:
Буферизованный вывод
Вывод в C++ может быть буферизован. Это означает, что всё, что выводится в файловый поток, не может сразу же быть записанным на диск (в конкретный файл). Это сделано, в первую очередь, по соображениям производительности. Когда данные буфера записываются на диск, то это называется очисткой буфера . Одним из способов очистки буфера является закрытие файла. В таком случае всё содержимое буфера будет перемещено на диск, а затем файл будет закрыт.
Буферизация вывода обычно не является проблемой, но, при определённых обстоятельствах, она может вызвать проблемы у неосторожных новичков. Например, когда в буфере хранятся данные и программа преждевременно завершает своё выполнение (либо в результате сбоя, либо путём вызова ). В таких случаях деструкторы классов файлового ввода/вывода не выполняются, файлы никогда не закрываются, буферы не очищаются и наши данные теряются навсегда. Вот почему хорошей идеей является явное закрытие всех открытых файлов перед вызовом exit().
Также буфер можно очистить вручную, используя метод ostream::flush() или отправив std::flush в выходной поток. Любой из этих способов может быть полезен для обеспечения немедленной записи содержимого буфера на диск в случае сбоя программы.
Интересный нюанс
: Поскольку std::endl; также очищает выходной поток, то его чрезмерное использование (приводящее к ненужным очисткам буфера) может повлиять на производительность программы (так как очистка буфера в некоторых случаях может быть затратной операцией). По этой причине программисты, которые заботятся о производительности своего кода, часто используют \n вместо std::endl для вставки символа новой строки в выходной поток, дабы избежать ненужной очистки буфера.
Режимы открытия файлов
Что произойдёт, если мы попытаемся записать данные в уже существующий файл? Повторный запуск программы выше (самая первая) показывает, что исходный файл полностью перезаписывается при повторном запуске программы. А что, если нам нужно добавить данные в конец файла? Оказывается, файлового потока принимают необязательный второй параметр, который позволяет указать программисту способ открытия файла. В качестве этого параметра можно передавать следующие флаги (которые находятся в классе ios):
app - открывает файл в режиме добавления;
ate - переходит в конец файла перед чтением/записью;
binary - открывает файл в бинарном режиме (вместо текстового режима);
in - открывает файл в режиме чтения (по умолчанию для ifstream);
out - открывает файл в режиме записи (по умолчанию для ofstream);
trunc - удаляет файл, если он уже существует.
Можно указать сразу несколько флагов путём использования .
ifstream по умолчанию работает в режиме ios::in;
ofstream по умолчанию работает в режиме ios::out;
fstream по умолчанию работает в режиме ios::in ИЛИ ios::out, что означает, что вы можете выполнять как чтение содержимого файла, так и запись данных в файл.
Теперь давайте напишем программу, которая добавит две строки в ранее созданный файл SomeText.txt:
#include
#include #include #include int main () using namespace std ; // Передаём флаг ios:app, чтобы сообщить fstream, что мы собираемся добавить свои данные к уже существующим данным файла, // мы не собираемся перезаписывать файл. Нам не нужно передавать флаг ios::out, // поскольку ofstream по умолчанию работает в режиме ios::out ofstream outf ("SomeText.txt" , ios :: app ) ; // Если мы не можем открыть файл для записи данных if (! outf ) // То выводим следующее сообщение об ошибке и выполняем exit() cerr << "Uh oh, SomeText.txt could not be opened for writing!" << endl ; exit (1 ) ; |
Последнее обновление: 31.10.2015
Для работы с каталогами в пространстве имен System.IO предназначены сразу два класса: Directory и DirectoryInfo .
Класс Directory
Класс Directory предоставляет ряд статических методов для управления каталогами. Некоторые из этих методов:
CreateDirectory(path) : создает каталог по указанному пути path
Delete(path) : удаляет каталог по указанному пути path
Exists(path) : определяет, существует ли каталог по указанному пути path. Если существует, возвращается true , если не существует, то false
GetDirectories(path) : получает список каталогов в каталоге path
GetFiles(path) : получает список файлов в каталоге path
Move(sourceDirName, destDirName) : перемещает каталог
GetParent(path) : получение родительского каталога
Класс DirectoryInfo
Данный класс предоставляет функциональность для создания, удаления, перемещения и других операций с каталогами. Во многом он похож на Directory. Некоторые из его свойств и методов:
Create() : создает каталог
CreateSubdirectory(path) : создает подкаталог по указанному пути path
Delete() : удаляет каталог
Свойство Exists : определяет, существует ли каталог
GetDirectories() : получает список каталогов
GetFiles() : получает список файлов
MoveTo(destDirName) : перемещает каталог
Свойство Parent : получение родительского каталога
Свойство Root : получение корневого каталога
Посмотрим на примерах применение этих классов
Получение списка файлов и подкаталогов
string dirName = "C:\\"; if (Directory.Exists(dirName)) { Console.WriteLine("Подкаталоги:"); string dirs = Directory.GetDirectories(dirName); foreach (string s in dirs) { Console.WriteLine(s); } Console.WriteLine(); Console.WriteLine("Файлы:"); string files = Directory.GetFiles(dirName); foreach (string s in files) { Console.WriteLine(s); } }Обратите внимание на использование слешей в именах файлов. Либо мы используем двойной слеш: "C:\\" , либо одинарный, но тогда перед всем путем ставим знак @: @"C:\Program Files"
Создание каталога
string path = @"C:\SomeDir"; string subpath = @"program\avalon"; DirectoryInfo dirInfo = new DirectoryInfo(path); if (!dirInfo.Exists) { dirInfo.Create(); } dirInfo.CreateSubdirectory(subpath);Вначале проверяем, а нету ли такой директории, так как если она существует, то ее создать будет нельзя, и приложение выбросит ошибку. В итоге у нас получится следующий путь: "C:\SomeDir\program\avalon"
Получение информации о каталоге
string dirName = "C:\\Program Files"; DirectoryInfo dirInfo = new DirectoryInfo(dirName); Console.WriteLine($"Название каталога: {dirInfo.Name}"); Console.WriteLine($"Полное название каталога: {dirInfo.FullName}"); Console.WriteLine($"Время создания каталога: {dirInfo.CreationTime}"); Console.WriteLine($"Корневой каталог: {dirInfo.Root}");Удаление каталога
Если мы просто применим метод Delete к непустой папке, в которой есть какие-нибудь файлы или подкаталоги, то приложение нам выбросит ошибку. Поэтому нам надо передать в метод Delete дополнительный параметр булевого типа, который укажет, что папку надо удалять со всем содержимым:
String dirName = @"C:\SomeFolder"; try { DirectoryInfo dirInfo = new DirectoryInfo(dirName); dirInfo.Delete(true); Console.WriteLine("Каталог удален"); } catch (Exception ex) { Console.WriteLine(ex.Message); }
String dirName = @"C:\SomeFolder"; Directory.Delete(dirName, true);
Перемещение каталога
string oldPath = @"C:\SomeFolder"; string newPath = @"C:\SomeDir"; DirectoryInfo dirInfo = new DirectoryInfo(oldPath); if (dirInfo.Exists && Directory.Exists(newPath) == false) { dirInfo.MoveTo(newPath); }При перемещении надо учитывать, что новый каталог, в который мы хотим перемесить все содержимое старого каталога, не должен существовать.
В этой статье мы узнаем, как считывать данные из файлов и записывать информацию в файлы в программах си. Файлы в си
используются для того, чтобы сохранять результат работы программы си и использовать его при новом запуске программы. Например можно сохранять результаты вычислений, статистику игр.
Чтобы работать с файлами в си необходимо подключить библиотеку stdio.h
#include
Чтобы работать с файлом в си
необходимо задать указатель на файл по образцу
FILE *имя указателя на файл;
Например
FILE *fin;
Задает указатель fin на файл
Дальше необходимо открыть файл и привязать его к файловому указателю. Для открытия файла в си на чтение используется команда
Имя указателя на файл= fopen("путь к файлу", "r");
Например следующая команда
fin = fopen("C:\\Users\\user\\Desktop\\data.txt", "r");
откроет файл data.txt, находящийся на рабочем столе по пути C:\\Users\\user\\Desktop Чтобы узнать путь к файлу можно выбрать файл мышью нажать на правую кнопку мыши и выбрать свойства файла. В разделе Расположение будет указан путь к файлу. Обратите внимание, что в си путь указывается с помощью двух слешей.
После работы с файлом в си, необходимо его закрыть с помощью команды
fclose(имя указателя на файл)
Считывание информации из текстового файла в Си
Чтобы можно было считывать русские символы из файла, необходимо настроить работу с Кириллицей с помощью команды
setlocale(LC_ALL, "Russian");
При этом необходимо в начале программы подключить #include
Оператор fscanf()
Для считывания слова из файла в си
используется команда fscanf(). Эта команда аналогична команде ввода информации с клавиватуры только первый параметр это указатель на файл
fscanf(указатель на файл,"%формат ввода данных1% форматввода данных2…",&перменная1,&переменная2…);
Например команда
fscanf(fin,"%d%d%d",&a,&b,&c);
считает из файла, который привязан к указателю на файл fin строку из трех целочисленных переменных
Разберем пример программы, которая считывает из текстового файла data.txt в которые записаны три столбца цифр информацию и записывает ее в массивы. Для каждого столбца информации свой массив. Подробно о .
#include
#include
main()
{ int a;
int b;
int c;
int i;
// определяем указатель на файл
FILE *fin;
// открываем файл на чтение
fin = fopen("C:\\Users\\user\\Desktop\\data.txt", "r");
// построчное считывание из файла
for (i=0;i<3;i++)
{
// считывание строки из трех значений файла и запись в массивы
fscanf(fin,"%d%d%d",&a[i],&b[i],&c[i]);
}
// вывод массивов на экран
for (i=0;i<3;i++)
{
printf("%d %d %d ",a[i],b[i],c[i]);
}
getch();
// закрытие файла
fclose(fin);
}
Построковое считывание информации из файла в СИ.Функция fgets ()
Оператор fscanf()
считывает из файла слово, т.е. до первого встречного пробела.
Чтобы считать из файла всю строку из файла в Си используется конструкция
if (NULL != fgets (строковая переменная, длина строки, указатель на файл))
{
действия при считывании строки
}
Например программа на Си которая считывает две строки из файла и выводит их на экран
#include
#include
#include
main()
{
// задаем строковые перменные
char st1;
char st2;
//определяем указатель на файл
FILE *fin;
// настриваем работу с Кириллицей
setlocale(LC_ALL, "Russian");
// открываем файл на чтение
fin = fopen("C:\\data.txt", "r");
// считываем первую строку из файла
if (NULL != fgets (st1, 100, fin))
{
// выводим строку на экран
printf("%s ",st1);}
// считываем вторую строку из файла
if (NULL != fgets (st2, 100, fin))
{
// выводим строку на экран
printf("%s ",st2);}
// закрываем файл на чтение
fclose(fin);
}
Запись информации в текстовый файл в Си
Для записи данных в файл в Си
, необходимо открыть файл в режиме записи
Имя указателя на файл= fopen("путь к файлу", "w");
Для записи в строку текстового файла используется команда fprnitf(), которая аналогична команде в си только первый параметр это указатель на файл
fprintf (имя указателя на файл,”%формат ввода”, переменные);
Например запись в файл out.txt значение переменной а
a=10;
fout = fopen("C:\\Users\\user\\Desktop\\out.txt", "w");
fprintf (fout,”%d”, a);
Пример программы на си которая запрашивает два числа и записывает в файл out.txt оба эти числа и их сумму
#include
#include
main()
{ int a;
int b;
int c;
FILE *fout;
fout = fopen("C:\\Users\\user\\Desktop\\out.txt", "w");
printf ("введите первое число ");
scanf("%d", &a);
printf ("введите второе число ");
scanf("%d", &b);
c=a+b;
fprintf(fout,"%d %d %d",a,b,c);
getch();
fclose(fout);
}