1 / 14

Работа с файлами

Сазонов Д.О. ПМиЭММ. Работа с файлами. Часть 1. ext2. fat32. cdfs. ntfs. vfat. Файлом можно назвать любые данные, записанные на внешний носитель, объединенные одним именем. Как OS представляет файл?.

adena-chang
Download Presentation

Работа с файлами

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Сазонов Д.О. ПМиЭММ Работа с файлами Часть 1

  2. ext2 fat32 cdfs ntfs vfat Файлом можно назвать любые данные, записанные на внешний носитель, объединенные одним именем Как OS представляет файл? В начале диска создается так называемая ТАБЛИЦА РАЗМЕЩЕНИЯ ФАЙЛОВ (File Allocation Table), в программировании просто называемая FAT. В данной таблице как раз содержится информация о файлах. Если быть точнее, то имя файла, его длинна, его атрибуты и номер по которому файл размещен на диске. Собственно говоря вы можете для примера загрузить программу DE (Disk Editor) из комплекта Norton Utilites. То, что вы там увидите и будет FAT. Например:

  3. Имя Рас Размер Дата Время Кластер Арх Т/Ч Сис Скр Кат Том IO DOS 40774 5-31-94 6:22 am 2 Т/Ч Сис Скр MSDOS DOS 38138 5-31-94 6:22 am 4 Т/Ч Сис Скр NIMNUL 0 7-05-98 6:46 pm 0 Арх Том хCANDISK LOG 732 7-31-96 1:58 pm 14 Арх AT.e.m.p ... 4294967295 15-31-07 7:63 pm 0 Т/Ч Сис Скр Том TEMP 0 7-05-98 7:11 pm 3599 Кат CONFIG SYS 124 7-29-96 8:38 pm 765 Арх AU.s.e.r .s. 4294967295 15-31-07 7:63 pm 0 Т/Ч Сис Скр Том USERS 0 7-05-98 7:16 pm 178 Кат QUIZ 0 7-28-96 4:53 pm 1091 Кат BOOTLOG PRV 24259 7-07-98 3:28 pm 11 Арх Скр LINUX 0 7-30-96 7:35 am 13 Кат Ag.a.m.e .s. 4294967295 15-31-07 7:63 pm 0 Т/Ч Сис Скр Том GAMES 0 7-05-98 9:05 pm 5676 Кат AUTOEXEC BAT 994 7-29-96 8:38 pm 799 Арх Т/Ч MSDOS SYS 1641 7-08-98 2:04 pm 811 Арх Т/Ч Сис Скр BOOTLOG TXT 24006 7-07-98 4:27 pm 9 Арх Скр SUHDLOG DAT 11821 7-07-98 3:17 pm 10669 Т/Ч Скр Когда пользователь хочет что либо сделать с файлом и дает об этом знать машине, компьютер сначала ищет имя этого файла в FAT, затем по имени определяет где этот файл начинается и сколько занимает - его начало и длину, ну а дальше все просто - загружается файл и с ним выполняются какие-либо действия из выше перечисленных. Теперь вы догадались, почему в одном каталоге не может быть два файла с одинаковыми именами? Собственно говоря, даже если такое и произойдет (в результате вмешательства опытного пользователя), то работать можно будет только с тем файлом, который находится первым по списку.

  4. Логический и физический файл. • Для удобства разделим файлы на две группы. Первая группа - это физический файл. Файл который реально находится на диске, и вообще любой файл. Логическим же файлом назовем файл с которым будем работать в программе, но как только мы выйдем из среды программирования или же перестанем работать с этим файлом он станет физическим. Зачем нужно такое разделение? • Дело в том, что все фалы на диске всегда представляют собой однотипную последовательность данный, где каждому элементу этих данных соответствует только одна ячейка. (вспомните массивы). Получается, что каждый файл это массив • char test_file[n] • Но, что делать, если нам нужно поместить в файл число типа integer или real, или какой-нибудь другой тип. Для этого в программе указывают тип данных которые, якобы будут записываться в файл, например integer (целый тип). Далее записывают элементы- если подумать логически, то раз в файл записываются элементы типа integer, то и сам файл тоже будет иметь этот тип. Но на самом деле это не так. Так как на каждое число в файле выделена одна ячейка, никак нельзя записать две. По этому каждое число разбивается на несколько частей. Этой разбивкой занимается компилятор и нам не надо об этом заботится, достаточно записать в файл любого типа, а компилятор сам преобразует его. Продемонстрировать это можно так (грубый пример).

  5. 42 76 2 4 6 7 Допустим дан файл: В каждой ячейке может поместиться только один символ. Это есть физический файл. Логический файл мы создаем, когда присваиваем файловой переменной тип файла. В Pascal: a: file of integer; Теперь мы записываем в него число, например 42 и число 76. Если бы это был массив, было бы: Задача же компилятора состоит в том, чтобы преобразовать число из двух символов в два числа по одному символу в каждом. По этому файл будет выглядеть так: Если приглядеться, то можно увидеть, что при записи в файл двух символов, компилятор меняет из местами.

  6. Представление файлов в С++ В отличии от PASCAL в С++ файл не надо описывать, для успешной работы достаточно иметь переменную где будет храниться номер файла - его описатель. Через этот номер и производится вся работа. Номер обычно это число целого типа. Например: int h; - вполне может сгодиться для размещения описателя файла. Открытие файла и закрыте файла Для работы с файлом его необходимо открыть, чтобы получить его номер и сказать компилятору что мы будем делать с этим файлом. Открытие осуществляется с помощью функции OPEN. Формат ее следующий: open(имя файла, режим доступа к файлу); функция возвращает целое значение, являющееся описателем файла и -1 если произошла ошибка при открытии файла. При открытии существует несколько режимов в которых можно открывать файл. Режим показывает для чего открывается данный файл.

  7. Рассмотрим эти режимы: O_RDONLY - открытие файла только для чтения O_WRONLY - открытие только для записи O_RDWR - открытие для чтения и для записи O_APPEND - добавление информации к существующему файлу O_CREAT - создание нового файла. Если файл уже существует, то он открывается, если такого файла нет, то он создается. O_BINARY - открывается бинарный файл (см. BASIC) O_TEXT - открывается текстовый файл. Данные режимы можно комбинировать. Используя оператор | (или) Например: Open('test', O_RDONLY | O_TEXT); Открывается текстовый файл test только для чтения. Итак открытие файла в С++ обычно выглядит так: Int h; ….. if ((h = open("TEST.$$$", O_CREAT)) == -1) {…..} т.е. сначала выполняется open("TEST.$$$", O_CREAT) открывается файл TEST.$$$ , затем по результату открытия описателю файла h присваивается номер файла или -1 если случилась ошибка, затем выполняется (h == -1) и если ошибка все таки случилась, выполняется то, что в скобках. Естественно после того как над файлом проделаны необходимые действия его необходимо закрыть. Закрыть файл можно с помощью функции close. Формат функции: сlose(описатель файла). Замечание: для работы функции OPEN необходимо подключение библиотеки fcntl.h. #include <fcntl.h>

  8. Запись в файл После того, как мы научились открывать файл необходимо научиться записывать в него. Это делает уже известная Вам из PASCAL функция write. write(описатель файла, массив или переменная значения которых будут записаны на диск, длина данных); В случае успешной записи write возвращает кол-во записанных байт.1 Замечание 1: Для записи write использует прерывание dos 40h, которое в свою очередь является копией прерывания 13h т.е. использует работу с диском через BIOS. Замечание 2: Одновременно записать можно только 65534 байта.

  9. Примеры записи файла: Ввести с клавиатуры текст и записать его в текстовый файл TEST.$$$ #include "stdafx.h" #include <fcntl.h> #include <string.h> #include <io.h> int main(void) { int h; char msg[255]; printf("Введите текст\n"); gets(msg); if ((h = open("TEST.$$$", O_CREAT | O_WRONLY | O_TEXT)) == -1) { printf("Ошибка открытия файла"); return 1; //выход из программы } write(h, msg, strlen(msg)); close(h); } Дан массив на 10 элементов целого типа. Записать его в файл. #include "stdafx.h" #include <fcntl.h> #include <io.h> int main(void) { int h; int msg[10]={2,4,12,4,2,7,4,5,7,6}; if ((h = open("TEST.$$$", O_CREAT | O_WRONLY)) == -1) { printf("Ошибка открытия файла"); return 1; //выход из программы } write(h, msg, sizeof(msg)); close(h); }

  10. #include "stdafx.h" #include <stdio.h> #include <io.h> #include <fcntl.h> #include <process.h> int main(void) { char msg[30]; int h, b; if ((h = open("TEST.$$$", O_RDONLY )) == -1) { printf("Файл не найден!\n"); return 1; } if ((b = read(h, msg, 30)) == -1) { printf("Не могу прочитать файл.\n"); exit(1); } else { printf("%s", msg); } return 0; } Чтение из файла Чтение из файла осуществляется с помощью функции read. Ее формат одинаков с write. Формат функции: read(описатель файла, переменная или массив куда будут считаны данные, кол-во байт сколько необходимо прочитать) Функция возвращает -1 если в процессе чтения произошла ошибка иначе кол-во прочитанных байт. Пример: необходимо прочитать и вывести на экран содержимое 30 первых байт файла TEST.$$$ созданного с помощью первого примера на запись файла.

  11. Иногда нам заранее не известно сколько байт надо прочитать или необходимо прочитать весь файл целиком. Тогда для этих целей мы можем использовать функцию распределения памяти malloc, чтобы выделить необходимое место. Формат функции: malloc(кол-во байт которые надо выделить) Функция возвращает указатель на выделенную область если помять выделена успешно или значение NULL в противном случае. Пример: void *m; ….. m=malloc(1000); ……. Далее нам потребуется определять размер файла. В этом нам поможет функция filelength. Формат функции: filelength(описатель файла) возвращает длину файла. Например: #include "stdafx.h" #include <stdio.h> #include <io.h> #include <fcntl.h> #include <process.h> int main(void) { int h; if ((h = open("TEST.$$$", O_RDONLY )) == -1) { printf("Файл не найден!\n"); return 1; } printf("Размер файла %d",filelength(h)); }

  12. Пример: Загрузить целиком файл в память и вывести его содержимое на экран. Ограничение: длина файла должна быть <=65534 байта. #include "stdafx.h" #include <stdio.h> #include <io.h> #include <alloc.h> #include <conio.h> #include <fcntl.h> #include <process.h> #include <sys\stat.h> int main(void) { void *msg; int h, b,size; clrscr(); if ((h = open("TEST.$$$", O_RDONLY )) == -1) { printf("Файл не найден!\n"); return 1; } size=filelength(h); if ((msg=malloc(size))==NULL) { printf("Не могу выделить память под файл!\n"); return 1; } if ((b = read(h, msg, size)) == -1) { printf("Не могу прочитать файл.\n"); exit(1); } else { printf("%s\n", msg); printf("Размер файла %d",size); } return 0; }

  13. Задание повышенной сложности Задания на практику • 1. Ввести числа в файл. Найти максимум, минимум и посчитать количесво отрицательных элементов. • 2. Ввести в текстовый файл фамилии студентов. Затем вывести из • файла те, которые начинаются на заданную букву: • 3. Сжатие. Дан текстовый файл в котором содержится произвольный набор символов (не содержащий цифр). • Необходимо найти в нем идущие рядом элементы и заменить их на кол-во повторений + сам повторяющийся • символ. • Например файл содержит: • ффывйыыааацуууццйцурлыыыыыыооооркоурккк • Его надо преобразовать так: • 2фывй2ы3ац3у2цйцурл6ы4оркор3к 4. Составить базу данных абитуриентов. На каждого абитуриентов запрограммировать следующие поля: Имя, Фамилия, Факультет, Оценка за экзамен по информатике, Оценка за экзамен по математике, Оценка за изложение Затем вывести абитуриентов успешно сдавших все экзамены. Если учитывать, что проходной бал - 13.

  14. Успехов!

More Related