Файловые системы. Типы файловых систем. Операции с файлами. Каталоги. Операции с каталогами. (5). Файловая структура и файловые системы

Лабораторная работа №10

ВЫВОД НА ДИСК И ПРИНТЕР

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

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

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

Что такое файловая структура

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

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

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

Рис. 1. Некоторое время данные хранятся в буфере

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

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


Рис. 2. Файловая структура хранит информацию, необходимую для нормального выполнения файловых операций

Почти все компиляторы Си и Си++ хранят информацию, необходимую для работы с файлами, в файле заголовков STDIO.H. Этот файл содержит определения констант, которые нужны для операций с файлами. Кроме того, он может содержать описание файловой структуры. Для того, чтобы воспользоваться функциями работы с файлами, программу следует начинать с инструкции

#include,

которая сделает файловые константы и описание файловой структуры доступными в процессе компиляции и компоновки программы.

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

Указатель на файл

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

FILE *file_pointer;

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

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

FILE *infile, *outfile;

Как открыть файл

Связь между программой и файлом устанавливается при помощи функции fopen(), синтаксис которой показан на рис. 3.

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


Рис. 3. Синтаксис функции fopen()

определенными правилами. Например, в операционной системе MS-DOS имя файла может состоять максимум из восьми символов, плюс расширение имени, состоящее не более чем из трех символов (расширение не является обязательным элементом). Если вы хотите вывести информацию на печатающее устройство, а не в дисковый файл, в качестве имени файла в кавычках указывается "PRN". При этом автоматически осуществляется вывод данных на принтер.

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

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

Например, если вы хотите создать файл с именем CD.DAT для хранения картотеки коллекции компакт-дисков, вы должны использовать следующие инструкции:

FILE *cdfile;cdfile = fopen("CD.DAT", "w");

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

FILE *cdfile;cdfile = fopen("CD.DAT", "r");

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

Если вы хотите распечатать информацию о вашей коллекции на принтере, используйте следующую последовательность инструкций:

FILE *cdfile;cdfile = fopen("PRN", "w");

Учтите, что вывод информации на принтер возможен только с режимом доступа "w".

Как Си/Си++ работает с файлами

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

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

Если файл открывается с режимом доступа "w", указатель также помещается в начало файла, так что первые введенные данные будут помещены в начало файла. При закрытии файла после введенного массива данных будет добавлен символ конца файла. Если файл к моменту его открытия с использованием режима доступа "w" уже существует, все содержащиеся в нем данные затираются и «поверх» них записывается новая информация, введенная с помощью процедуры записи. Любые данные, которые могут остаться не уничтоженными, располагаются после нового символа конца файла, так что к ним уже нельзя будет обратиться при следующем чтении данных из файла. Таким образом, любая попытка записи данных в существующий файл с использованием режима доступа "w" приведет к уничтожению хранящейся в нем на данный момент информации. Это произойдет даже в том случае, если файл будет просто открыт и закрыт, без записи каких-либо данных.

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

Как закрыть файл

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

Fclose(file_pointer);

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

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

Листинг 1. Использование одного указателя файла в двух операциях.

FILE *cdfile;if((cdfile = fopen("CD.DAT", "w")) == NULL) { puts("Невозможно открыть файл"); exit(); }/* Здесь должны располагаться инструкции записи в файл */fclose(cdfile);if((cdfile = fopen("CD.DAT", "r")) == NULL) { puts("Невозможно открыть файл"); exit(); }/* В этом месте должны быть записаны инструкции чтения из файла */fclose(cdfile);

Здесь файл сначала открывается с использованием режима доступа "w", затем в него записывают данные. Во второй раз файл открывается с использованием режима доступа "r", что позволяет прочитать данные и вывести их на экран.

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

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

Функции ввода и вывода

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

· посимвольная запись данных в файл или вывод их на принтер с использованием функции putc() или fputc();

· посимвольное чтение данных из файла с использованием функции getc() или fgetc();

· построчная запись данных в файл или вывод их на принтер с использованием функции fputs();

· построчное чтение данных из файла с использованием функции fgets();

· форматированный вывод символов, строк или чисел на диск или на принтер с помощью функции fprintf();

· форматированный ввод символов, строк или чисел из файла с помощью функции fscanf();

· запись целой структуры с использованием функции fwrite();

· чтение целой структуры с использованием функции fread().

Работа с символами

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

/*fputc.c*/#include main() { FILE *fp; char letter; if((fp = fopen("MYFILE","w"))==NULL) { puts("Невозможно открыть файл"); exit(); } do { letter=getchar(); fputc(letter, fp); } while(letter != "\r"); fclose(fp); }

Файл открывается с режимом доступа "w". Если файл с именем MYFILE не существует к моменту выполнения программы, он будет создан. В цикле do, с помощью функции getchar(), осуществляется ввод последовательности символов, которые затем записываются в файл с помощью функции putc(). Синтаксис записи putc() таков:

Putc(char_variable, file_pointer);

С теми же аргументами может использоваться и функция fputc().

Цикл выполняется до тех пор, пока не нажата клавиша Enter , которая вводит код «возврат каретки» (\r), после чего файл закрывается.

Работа со строками

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

Функция fputs() имеет следующий синтаксис:

Fputs(string_variable, file_pointer);

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

/*fputc.c*/#include main() { FILE *fp; char flag; char name; if((fp = fopen("MYFILE","w"))==NULL) { puts("Невозможно открыть файл"); exit(); } flag = "y"; while(flag != "n") { puts("Введите имя"); gets(name); fputs(name, fp); fputs("\n",fp); printf("Желаете ввести другое имя?"); flag=getchar(); putchar("\n"); } fclose(fp); }

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

Если ваш компилятор может использовать функцию strlen(), можно несколько упростить процедуру ввода, используя следующие инструкции:

Printf("Пожалуйста, введите имя: ");gets(name);while(strlen(name) > 0) { fputs(name, fp); fputs("\n", fp); printf("Пожалуйста, введите имя: "); gets(name); }

Символы, которые вы набираете на клавиатуре, присваиваются строковой переменной name, а затем проверяется, не оказалась ли длина строки равной 0. Если на запрос сразу же нажать клавишу Enter, строка будет иметь нулевую длину и выполнение цикла прекратится. Если до нажатия Enter ввести хотя бы один символ, строка и код «новая строка» будут записаны на диск.

Некоторые компиляторы позволяют еще более упростить алгоритм ввода строки, например, так:

Printf("Пожалуйста, введите имя: ");while(strlen(gets(name)) > 0) { fputs(name, fp); fputs("\n", fp); printf("Пожалуйста, введите имя: "); }

где ввод строки выполняется внутри условия while.

Для того чтобы напечатать строку на принтере, вместо записи ее на диск используется имя файла "prn". Чтобы открыть файл, требуется указать:

If ((fp = fopen("prn", "w")) == NULL)

Для создания программы печати длина строки определяется равной 81 символу, чтобы строка могла уместиться во всю ширину экрана, прежде чем будет нажата клавиша Enter . В Листинге 2 приводится текст программы, которая демонстрирует, как можно написать простой текстовый процессор. Строка не посылается на принтер до тех пор, пока не нажата клавиша Enter , что позволяет с помощью клавиши Backspace корректировать ошибки ввода строки.

Листинг 2. Программа вывода строки на печатающее устройство.

/*wp.c*/#include "stdio.h"main() { FILE *fp; char line; if ((fp = fopen("prn", "w")) == NULL) { puts("Принтер не готов к работе"); exit(); } puts("Введите текст, после ввода каждой строки нажимайте Enter\n"); puts("Для прекращения ввода нажмите Enter в начале новой строки\n"); gets(line); while (strlen(line) > 0) { fputs(line, fp); fputs("\n", fp); gets(line); } fclose(fp); }

Чтение строк

Чтение строк из файла осуществляется с помощью функции fgets(). Синтаксис функции:

Fgets(string_variable, lenght, file_pointer);

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

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

/*fgets.c"/#include "stdio.h"main() { FILE *fp; char name; if ((fp = fopen("MYFILE", "r")) == NULL) { puts("Невозможно открыть файл"); exit(); } while(fgets(name, 12, fp) != NULL) { printf(name); } fclose(fp); }

Ввод выполняется внутри цикла while до тех пор, пока значение читаемого символа не равно NULL. Как только указатель достигнет конца файла, строковой переменной присваивается значение NULL. При построчном чтении из файла для указания конца файла всегда используется NULL, а EOF используют при посимвольном чтении.

Если вы пишете программу, предназначенную для чтения любого текстового файла, указывайте значение аргумента lenght равным 80.

Кстати, обратите внимание, что функция printf() используется в этом примере для вывода содержимого строковой переменной без указателей формата. Каждая строка, читаемая из файла, включает код «новая строка», который был записан в файл в инструкции fputs("\n", fp);, и никаких дополнительных кодов «новая строка» в параметры функции printf() включать не требуется.

Листинг 3. Форматированный вывод.

/*fprintf.c*/#include "stdio.h"main() { FILE *fp; char name; int quantity; float cost; if ((fp = fopen("MYFILE", "w")) == NULL) { puts("Невозможно открыть файл"); exit(); } printf("Введите наименование товара: "); gets(name); while (strlen(name) > 0) { printf("Введите цену товара: "); scanf("%f", &cost); printf("Введите количество единиц товара: "); scanf("%d", &quantity); fprintf(fp, "%s %f %d\n", name, cost, quantity); printf("Введите наименование товара: "); gets(name); } fclose(fp); }

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

Do { printf("Введите наименование товара: "); gets(name); printf("Введите цену: "); scanf("%f", &cost); printf("Введите количество единиц товара: "); scanf("%d", &quantity); fprintf(fp, "%s %f %d\n", name, cost, quantity); }while (strlen(name) > 0);

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

Внутри цикла while данные о цене и количестве каждого наименования товара вводятся с использованием функции scanf(), а затем записываются на диск с помощью инструкции

Fprintf(fp, "%s %f %d\n", name, cost, quantity);

Обратите внимание, что код «новая строка» записывается в файл в конце каждой строки. Если просмотреть содержимое файла с помощью команды TYPE операционной системы MS-DOS, то каждая строка инвентарной описи и на экране будет начинаться с новой строки:

Если бы код «новая строка» не был записан на диск, текст выводился бы подряд, в одну строку на экране, и выглядел примерно так:

Дискеты 1.120000 100лента 7.340000 150картридж 75.000000 3

Заметьте, что при этом отсутствует пробел между числом, показывающим количество единиц одного товара, и наименованием следующего. Даже при таком способе записи можно без проблем осуществлять чтение из этого файла, так как компилятор в состоянии различить конец числового значения и начало строки, но что произойдет, если последним значением для каждого наименования товара окажется строка с названием фирмы-производителя? Информация в файле будет выглядеть примерно таким образом:

Дискеты 1.120000 Memoryexлента 7.340000 Okaydataкартридж 75.000000 HP

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

Дискеты 1.120000 Memoryexлента

Все выведенные на диск данные, даже значения типа int или float, хранятся в виде текстовых символов. Об этом мы будем говорить чуть позже.

Листинг 4. Чтение форматированного текста из файла.

/*fscanf.c*/#include "stdio.h"main() { FILE *fp; char name; int quantity; float cost; if ((fp = fopen("MYFILE", "r")) == NULL) { puts("Невозможно открыть файл"); exit(); } while (fscanf(fp, "%s%f%d", name, &cost, &quantity) != EOF) { printf("Наименование товара: %s\n", name); printf("Цена: %.2f\n", cost); printf("Количество единиц: %d\n", quantity); } fclose(fp); }

Работа со структурами

Одним из способов преодолеть ограничения функции scanf() является объединение элементов данных в структуру с тем, чтобы впоследствии осуществлять ввод и вывод структур целиком. Структуру можно записать на диск с помощью функции fwrite() и прочитать из файла с помощью функции fread().

Синтаксис функции fwrite() такой:

Fwrite(&structure_variable, structure_size, number_of_structures, file_pointer);

На первый взгляд, эта инструкция выглядит несколько устрашающей, но на самом деле использовать ее очень легко:

· &structure_variable - имя структурной переменной с оператором получения адреса, сообщающим компилятору стартовый адрес информации, которую мы хотим записать на диск;

· structure_size - это количество символов в структуре; не обязательно подсчитывать его самому, для этого можно использовать библиотечную функцию sizeof(), записанную следующим образом:

Sizeof(structure_variable)

которая автоматически определит размер указанной структуры;

· number_of_structures - это целое число, определяющее количество структур, которые мы хотим записать в один прием; здесь всегда следует указывать число 1, если только вы не собираетесь создать массив структур и записать его одним большим блоком;

· file_pointer - указатель на файл.

В качестве примера предположим, что вы хотите записать на диск сведения о своей коллекции компакт-дисков. Используя структуру CD, которую мы подробно разбирали ранее, пишем инструкцию: fwrite(&disc, sizeof(disc), 1, fp);

Выполнение этой инструкции иллюстрирует рис. 5.

Текст программы, которая вводит данные в структуру CD, а затем сохраняет ее на диске, приведен в Листинге12.5. Для ввода имени создаваемого файла используется функция gets(). Переменная, в которой хранится имя файла, используется функцией fopen() для того, чтобы открыть файл.

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



Рис. 5. Синтаксис функции fwrite() в инструкции записи структуры CD

Листинг 5. Запись структуры CD.

/*fwrite.c*/#include "stdio.h"main() { FILE *fp; struct CD { char name; char description; char category; float cost; int number; } disc; char filename; printf("Введите имя файла, который вы желаете создать: "); gets(filename); if ((fp = fopen(filename, "w")) == NULL) { printf("Невозможно открыть файл %s\n", filename); exit(); } puts("Введите сведения о диске\n"); printf("Введите название диска: "); gets(disc.name); while (strlen(disc.name) > 0) { printf("Введите описание: "); gets(disc.description); printf("Введите категорию: "); gets(disc.category); printf("Введите цену: "); scanf("%f", &disc.cost); printf("Введите номер ячейки: "); scanf("%d", &disc.number); fwrite(&disc, sizeof(disc), 1, fp); printf("Введите название: "); gets(disc.name); } fclose(fp); }

Чтение структур

Fread(&structure_variable, structure_size, number_of_structures, file_pointer);

За исключением имени функции эта инструкция полностью совпадает с записью функции fwrite(). Программа, в которой из файла считывается структура CD, приведена в Листинге 6. Для чтения данных используется цикл while:

While (fread(&disc, sizeof(disc), 1, fp) == 1)

Функция fread() возвращает значение, соответствующее количеству успешно прочитанных структур. Так как в аргументе функции мы указали, что читать следует по одной структуре, функция возвращает значение 1. Цикл while будет выполняться до тех пор, пока считывание структур с диска проходит успешно. Если чтение структуры становится невозможным, например потому, что достигнут конец файла, функция возвращает значение 0, и выполнение цикла прекращается.

Листинг 6. Чтение структуры CD с диска.

/*fread.c*/#include "stdio.h"main() { FILE *fp; struct CD { char name; char description; char category; float cost; int number; } disc; char filename; printf("Введите имя файла, который желаете открыть: "); gets(filename); if ((fp = fopen(filename, "r")) == NULL) { printf("Невозможно открыть файл %s\n", filename); exit(); } while (fread(&disc, sizeof(disc), 1, fp) == 1) { puts(disc.name); putchar("\n"); puts(disc.description); putchar("\n"); puts(disc.category); putchar("\n"); printf("%f", disc.cost); putchar("\n"); printf("%d", disc.number); } fclose(fp); }

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

Таблица 1. Функции ввода в файл и вывода из файла.

Чтение в массив

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

В Листинге 7 приведен текст программы, осуществляющей чтение информации из файла, содержащего данные о коллекции компакт-дисков, в массив структур CD (предполагается, что их количество не превышает 20). Индекс используется для того, чтобы каждая считанная из файла структура сохранялась в отдельном элементе массива disc. После того как очередная структура прочитана и выведена на экран, стоимость очередного диска добавляется к сумме, отражающей общую стоимость коллекции, а значение индекса и счетчика увеличивается за счет выполнения следующих инструкций:

Total = total + disc.cost;index++;count++;

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

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

Листинг 7. Чтение структуры в массив.

/*rarray.c*/#include "stdio.h"main() { FILE *fp; struct CD { char name; char description; char category; float cost; int number; } disc; int index, count; float total; count = 0; total = 0; char filename; printf("Введите имя файла данных: "); gets(filename); while ((fp = fopen(filename, "r")) == NULL) { printf("Невозможно открыть файл %s\n", filename); printf("Введите имя файла данных: "); gets(filename); } index = 0; while (fread(&disc, sizeof(disc), 1, fp) == 1) { puts(disc.name); putchar("\n"); puts(disc.description); putchar("\n"); puts(disc.category); putchar("\n"); printf("%f", disc.cost); putchar("\n"); printf("%d", disc.number); total = total + disc.cost; index++; count++; } fclose(fp); printf("Общая стоимость коллекции составляет %.2f\n", total); printf("Коллекция содержит %.d дисков\n", count); }

Листинг 8. Программа копирования содержимого файлов.

/*filecopy.c*/#include "stdio.h"main() { FILE *fp1, *fp2; char infile, outfile; int letter; printf("Введите имя файла для чтения: "); gets(infile); if ((fp1 = fopen(infile, "r")) == NULL) { printf("Невозможно открыть файл %s", infile); exit(); } printf("Введите имя файла для записи: "); gets(outfile); if ((fp2 = fopen(infile, "w")) == NULL) { printf("Невозможно открыть файл %s", outfile); fclose(fp1); exit(); } while ((letter = fgetc(fp1)) != EOF) { putchar(letter); fputc(letter, fp2); } fclose(fp1); fclose(fp2); }

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


Рис. 6. Функция fprintf() записывает числовые значения в виде текстовых символов

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

Функция fprintf() записывает все данные в виде текста. Например, если использовать fprintf() для записи числа 34.23 на диск, пять символов будут записаны так, как это показано на рис. 6. Если в дальнейшем для чтения данных из файла используется функция fscanf(), символы будут преобразованы в числовое значение и в таком виде записаны в переменную.

Вследствие того, что функция fprintf() записывает данные в виде текста, чтение из файла можно осуществлять и с помощью функций getc(), fgetc() или fgets(). Однако эти функции будут читать информацию в виде «печатных» символов. Например, если использовать функцию fgets(), числа будут считываться в виде символов, являющихся частью строки. При отображении на экране или печати на принтере данных, прочитанных с использованием функции fgets() или fgetc(), вы будете лишены возможности выполнения арифметических операций над отдельными элементами данных.

Двоичный формат

Для сохранения числовых переменных в двоичном формате используется функция fwrite(). Записанные таким образом данные на диске займут столько же места, сколько и в памяти. Если просмотреть содержимое такого файла с помощью команды TYPE, мы увидим на месте числовых значений бессмысленные буквы и значки. Это ASCII-символы, эквивалентные записанным в файл значениям.

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

Печать данных

С технической точки зрения вывести данные на принтер можно с помощью любой функции вывода: посимвольно, построчно, форматированными строками или структурами. Единственное, что необходимо, - это указать имя файла "prn" и режим доступа "w".

Однако «поструктурная» печать с помощью функции fwrite() практически не используется, так как числовые данные при этом будут напечатаны в двоичном формате в виде загадочных символов. Вместо этого для печати структур используется функция fprintf(), как это показано в Листинге 9. В этой программе открываются два файла: дисковый файл открывается для чтения, а файл принтера - для вывода.

Листинг 9. Чтение и печать содержимого дискового файла.

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

Инструкции

Fprintf(ptr, "\n\n");

выводят по две пустые строки между отдельными структурами CD.

Проектирование программы

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

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

Файлы и файловые структуры

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

Наличие нескольких логических разделов на одном жестком диске обеспечивает пользователю следующие преимущества:


  • Можно хранить операционную систему в одном логическом разделе, а данные - в другом, что позволит переустанавливать операционную систему, не затрагивая данные;

  • На одном жестком диске в различные логические разделы можно установить разные операционные системы;

  • Обслуживание одного логического раздела не затрагивает другие разделы.

Устройства внешней памяти и логические разделы диска имеют логическое имя .

В ОС Windows приняты логические имена, состоящие из латинской буквы и двоеточия:


  • для дисководов гибких дисков (дискет) – A: и B:

  • для жестких дисков и логических разделов –C:, D:, E: и т.д.

  • для оптических дисководов – имена, следующие после жестких дисков (например, F:)

  • Для подключаемой к компьютеру флеш-памяти – следующее имя (например, G:)
В ОС Linux приняты другие правила именования дисков:

  • Логические разделы, принадлежащие первому жесткому диску – имена hda1, hda2 и т.д.;

  • Логические разделы, принадлежащие второму жесткому диску получают имена hdb1, hdb2 и т.д.
Все программы и данные хранятся во внешней памяти компьютера в виде файлов.
^ Файл – это поименованная область внешней памяти.
Файловая система – это часть ОС, определяющая способ организации, хранения и именования файлов на носителях информации.
Файл характеризуется набором параметров (имя, размер, дата создания, дата последнего изменения) и атрибутами, используемыми операционной системой для его обработки (архивный, системный, скрытый, только для чтения). Размер файла выражается в байтах.

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

Имя файлу дает пользователь. Расширение имени обычно задается программой автоматически при сохранении файла. Расширение позволяет пользователю его тип, а операционной системе открыть файл с помощью нужного приложения.
В ОС Windows в имени файла зап0рещено использование следующих символов: \, /, :, *, ?, ”, |. В Linux эти символы, кроме /, допустимы.

Операционная система Linux, в отличие от Windows, различают строчные и прописные буквы в имени файла: например FILE.txt, file.txt и FiLe.txt – это в Linux три разных файла.

Наиболее распространенные типы файлов и расширений:


Тип файла

Примеры расширений

Системный файл

drv, sys

Текстовый файл

txt, rtf, doc, docx, odt

Графический файл

bmp, gif, jpg, tif, png, psd

Web-страница

htm, html

Звуковой файл

wav, mp3, midi, kar, ogg

Видеофайл

avi, mpeg

Архив

zip, rar

Электронная таблица

xls, ods

Код (текст) программы на языках программирования

bas, pas

В ОС Linux выделяют следующие типы файлов:


  • обычные файлы – файлы с программами и данными

  • каталоги – файлы, содержащие информацию о каталогах

  • ссылки – файлы, содержащие ссылки на другие файлы

  • специальные файлы устройств – файлы, используемые для представления физических устройств компьютера (жестких и оптических дисководов, принтера, звуковых колонок и т.д.)

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

Каталог – это поименованная совокупность файлов и подкаталогов (вложенных каталогов).
Каталог самого верхнего уровня называется корневым каталогом .

В ОС Windows любой информационный носитель имеет корневой каталог, который создается операционной системой без участия пользователя. Обозначаются корневые каталоги добавлением к логическому имени соответствующего устройства внешней памяти знака «\» (обратный слеш): А:\, С:\, В:\ и т.д.

В Linux каталоги жестких дисков или их логических разделов не принадлежат верхнему уровню файловой системы (не являются корневыми каталогами). Они «монтируются» в каталог mnl. Другие устройства внешней памяти (гибкие, оптические и флеш-диски) «монтируются» в каталог media. Каталоги mnt и media в свою очередь, «монтируются» в единый корневой каталог, который обозначается знаком «/» (прямой слеш).

Файловая структура диска – это совокупность файлов на диске и взаимосвязей между ними.

Файловые структуры бывают простыми и многоуровневыми (иерархическими).

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

Графическое изображение иерархической файловой структуры называется деревом .

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

Последовательно записанные путь к файлу и имя файла составляют полное имя файла .
Пример полного имени файла в ОС Windows:

E:\изображения\фото\Поездка.jpeg

Общее. В теории информатики определены следующие три основных типа структур данных – линейная, табличная, иерархическая. Пример книга: последовательность листов – линейная структура. Части, разделы, главы, параграфы – иерархия. Оглавление – таблица – связывает – иерархическую с линейной. У структурированных данных появляется новый атрибут - Адрес. И так:

      Линейные структуры (списки, вектора). Обычные списки. Адрес каждого элемента однозначно определяется его номером. Если все элементы списка имеют равную длину – вектора данных.

      Табличные структуры (таблицы, матрицы). Отличие таблицы от списка – каждый элемент – определяется адресом, состоящим не из одного, а нескольких параметров. Самый распространенный пример – матрица - адрес – два параметра – номер строки и номер столбца. Многомерные таблицы.

      Иерархические структуры. Используются для представления нерегулярных данных. Адрес – определяется маршрутом – от вершины дерева. Файловая система – компьютера. (Маршрут может превысить – величину данных, дихотомия – всегда два разветвления – влево и вправо).

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

    Основные элементы файловой системы

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

Файл - это именованная область внешней памяти, в которую можно записывать и из которой можно считывать данные. Три параметра:

    последовательность произвольного числа байтов,

    уникальное собственное имя (фактически – адрес).

    данные одного типа – тип файла.

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

Первая, в современном понимании, развитая файловая система была разработана фирмой IBM для ее серии 360 (1965-1966 годы). Но в нынешних системах она практически не применяется. Использовала списочные структуры данных (ЕС- том, раздел, файл).

Большинство из Вас знакомо с файловыми системами современных ОС. Это прежде всего MS DOS, Windows, а некоторые с построением файловой системы для различных вариантов UNIX.

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

Именование файлов. Все современные файловые системы поддерживают многоуровневое именование файлов за счет поддержания во внешней памяти дополнительных файлов со специальной структурой - каталогов. Каждый каталог содержит имена каталогов и/или файлов, содержащихся в данном каталоге. Таким образом, полное имя файла состоит из списка имен каталогов плюс имя файла в каталоге, непосредственно содержащем данный файл. Разница между способами именования файлов в разных файловых системах состоит в том, с чего начинается эта цепочка имен. (Unix, DOS-Windows)

Защита файлов. Системы управления файлами должны обеспечивать авторизацию доступа к файлам. В общем виде подход состоит в том, что по отношению к каждому зарегистрированному пользователю данной вычислительной системы для каждого существующего файла указываются действия, которые разрешены или запрещены данному пользователю. Существовали попытки реализовать этот подход в полном объеме. Но это вызывало слишком большие накладные расходы как по хранению избыточной информации, так и по использованию этой информации для контроля правомочности доступа. Поэтому в большинстве современных систем управления файлами применяется подход к защите файлов, впервые реализованный в ОС UNIX (1974). В этой системе каждому зарегистрированному пользователю соответствует пара целочисленных идентификаторов: идентификатор группы, к которой относится этот пользователь, и его собственный идентификатор в группе. Соответственно, при каждом файле хранится полный идентификатор пользователя, который создал этот файл, и отмечается, какие действия с файлом может производить он сам, какие действия с файлом доступны для других пользователей той же группы, и что могут делать с файлом пользователи других групп. Эта информация очень компактна, при проверке требуется небольшое количество действий, и этот способ контроля доступа удовлетворителен в большинстве случаев.

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

    Журналирование в файловых системах. Общие принципы.

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

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

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

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

    Файловая система MS-DOS (FAT)

Файловая система MS-DOS представляет собой древовидную файловую систему для небольших дисков и простых структур каталогов, в корне которой находится корневой каталог, а листьями являются файлы и другие каталоги, возможно пустые. Размещение файлов под управлением этой файловой системы происходит по кластерам, размер которых может колебаться от 4 КБ до 64 КБ кратно 4, без использования свойства смежности смешанным способом выделения дисковой памяти. Например, на рисунке показано три файла. Файл File1.txt является достаточно большим: он задействует три следующих друг за другом блока. Небольшой файл File3.txt использует пространство только одного размещаемого блока. Третий файл File2.txt. является большим фрагментированным файлом. В каждом случае точка входа указывает на первый распределяемый блок, принадлежащий файлу. Если файл использует несколько распределяемых блоков, то предшествующий блок указывает на следующий в цепочке. Значение FFF отождествляется с концом последовательности.

Дисковый раздел FAT

Для эффективного доступа к файлам используется таблица размещения файлов – File Allocation Table, которая размещается в начале раздела (или логического диска). Именно от названия таблицы размещения и происходит название этой файловой системы – FAT. В целях защиты раздела на нем хранятся две копии FAT, на тот случай, если одна из них окажется поврежденной. Кроме того, таблицы размещения файлов должны размещаться по строго фиксированным адресам, чтобы файлы, необходимые для запуска системы, были размещены корректно.

Таблица размещения файлов состоит из 16-разрядных элементов и содержит следующую информацию о каждом кластере логического диска:

    кластер не используется;

    кластер используется файлом;

    плохой кластер;

    последний кластер файла;.

Так как каждому кластеру должен быть присвоен уникальный 16-разрядный номер, то следовательно, FAT поддерживает максимально 216, или 65 536 кластеров на одном логическом диске (да еще некоторую часть кластеров резервирует для своих нужд). Таким образом получаем предельный размер диска, обслуживаемого MS-DOS, в 4 ГБ. Размер кластера можно увеличить или уменьшить в зависимости от размера диска. Однако, когда размер диска превышает некоторую величину, кластеры становятся слишком большого размера что ведет к внутренней дефрагментации диска. Кроме информации о файлах, в таблице размещения файлов может быть помещена информация и о каталогах. При этом каталоги рассматриваются как специальные файлы с 32-байтовыми элементами для каждого файла, содержащегося в этом каталоге. Корневой каталог имеет фиксированный размер – 512 записей для жесткого диска, а для дискет этот размер определяется объемом дискеты. Кроме того, корневой каталог расположен сразу же после второй копии FAT, поскольку в нем находятся файлы, необходимые загрузчику MS-DOS.

При поиске файла на диске MS-DOS вынуждена просматривать структуру каталога, чтобы найти его. Например, чтобы запустить исполняемый файл С:\Program\NC4\nc.exe находит исполнимый файл, выполнив следующие действия:

    читает корневой каталог диска C: и ищет в нем каталог Program;

    читает начальный кластер Program и ищет в этом каталоге запись о вложенном каталоге NC4;

    читает начальный кластер вложенного каталога NC4 и ищет в нем запись о файле nc.exe;

    читает все кластеры файла nc.exe.

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

Достоинства FAT

    Является лучшим выбором для логических дисков небольшого размера, т.к. стартует с минимальными накладными расходами. На дисках, размер которых не превышает 500 МБ, она работает с приемлемыми характеристиками.

Недостатки FAT

    Поскольку размер записи о файле ограничен 32 байтами, а информация должна включать в себя и размер файла и дату, и атрибуты и т.д., то размер под название файла также ограничен и не может превышать 8+3 символа на каждый файл. Использование так называемых коротких имен файлов делает FAT менее привлекательной для использования по сравнению с другими файловыми системами.

    Использование FAT на дисках, объем которых превышает 500 МБ нерационально по причине дефрагментации диска.

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

    Скорость выполнения операций в FAT происходит обратно пропорционально глубине вложенности каталогов и объему диска.

    Файловая система UNIX – систем (ext3)

Современная, мощная и бесплатная операционная система Linux предоставляет широкую территорию для разработки современных систем и пользовательского программного обеспечения. Некоторые из наиболее интересных разработок в недавних ядрах Linux это новые, высоко производительные технологии для управления хранением, размещением и обновлением данных на диске. Один из наиболее интересных механизмов – это файловая система ext3, которая интегрируется в ядро Linux начиная с версии 2.4.16, и уже доступна по умолчанию в Linux дистрибутивах от компаний Red Hat и SuSE.

Файловая система ext3 является журналируемой файловой системой, 100% совместимой со всеми утилитами созданными для создания, управления и тонкой настройки файловой системы ext2, которая используется в Linux системах несколько последних лет. Перед детальным описанием различий между файловыми системами ext2 и ext3, уточним терминологию файловых систем и хранения файлов.

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

Файловые системы созданы на разделах диска для упрощения хранения и организации данных в форме файлов и директорий. Linux, как Unix система, использует иерархическую файловую систему составленную из файлов и директорий, которые соответственно содержат либо файлы либо каталоги. Файлы и директории в файловой системе Linux становятся доступным пользователю путем их монтирования (команда «mount»), которая обычно является частью процесса загрузки системы. Список файловых систем доступных для использования хранится в файле /etc/fstab (FileSystem TABle). Список файловых систем не смонтированных в данные момент системой хранится в файле /etc/mtab (Mount TABle).

В момент монтирования файловой системы в процессе загрузки, бит в заголовке («чистый бит» / «clean bit») стирается, это означает что файловая система используется, и что структуры данных используемые для управления размещением и организации файлов и директорий, в данной файловой системы могут быть изменены.

Файловая система расценивается как целостная если все блоки данных в ней либо используются, либо свободны; каждый размещенный блок данных занят одним и только одним файлом или директорией; все файлы и директории могут быть доступны после обработки серии других директорий в файловой системе. Когда система Linux намеренно прекращает работу используя команды оператора, все файловые системы размонтируются. Размонтирование файловой системы в процессе завершения работы устанавливает «чистый бит» в заголовок файловой системы, указывая на то, что файловая система была размонтирована должным образом и, тем самым, может рассматриваться как целостная.

Года отладки и переработки файловой системы и использование улучшенных алгоритмов для записи данных на диск в большой степени уменьшили повреждение данных вызываемых приложениями или самим ядром Linux, но устранение повреждения и потери данных в связи с отключением питания и другими системными проблемами до сих пор является сложной задачей. В случае аварийной остановки или простого отключения Linux системы без использования стандартных процедур остановки работы «чистый бит» в заголовке файловой системы не устанавливается. При следующей загрузке системы, процесс монтировки обнаруживает, что система не маркирована как «чистая», и физически проверяет ее целостность использую Linux/Unix утилиту проверки файловой системы "fsck" (File System ChecK).

Существует несколько журналируемых файловых систем доступных для Linux. Наиболее известные из них: XFS, журналируемая файловая система разработанная Silicon Graphics, но сейчас выпущенная открытым кодом (open source); RaiserFS, журналируемая файловая система разработанная специально для Linux; JFS, журналируемая файловая система первоначально разработанная IBM, но сейчас выпущенная как открытый код; ext3 – файловая система разработанная доктором Стефаном Твиди (Stephan Tweedie) в Red Hat, и несколько других систем.

Файловая система ext3 – это журналируемая версия Linux файловой системы ext2. Файловая система ext3 имеет одно значительно преимущество перед другими журналируемыми файловыми системами – она полностью совместима с файловой системой ext2. Это делает возможным использование всех существующих приложений разработанных для манипуляции и настройки файловой системы ext2.

Файловая система ext3 поддерживается ядрами Linux версии 2.4.16 и более поздними, и должна быть активизирована использованием диалога конфигурации файловых систем (Filesystems Configuration) при сборке ядра. В Linux дистрибутивы, такие как Red Hat 7.2 и SuSE 7.3 уже включена встроенная поддержка файловой системы ext3. Вы можете использовать файловую систему ext3 только в том случае, когда поддержка ext3 встроена в ваше ядро и у вас есть последние версии утилит «mount» и «e2fsprogs».

В большинстве случаев перевод файловых систем из одного формата в другой влечет за собой резервное копирование всех содержащихся данных, переформатирование разделов или логических томов, содержащих файловую систему, и затем восстановление всех данных на эту файловую систему. В связи с совместимостью файловых систем ext2 и ext3, все эти действия можно не проводить, и перевод может быть сделать с помощью одной команды (запущенной с полномочиями root):

# /sbin/tune2fs -j <имя-раздела >

Например, перевод файловой системы ext2 расположенной на разделе /dev/hda5 в файловую систему ext3 может быть осуществлен с помощью следующей комманды:

# /sbin/tune2fs -j /dev/hda5

Опция "-j" команды "tune2fs" создает журнал ext3 на существующей ext2 файловой системе. После перевода файловой системы ext2 в ext3, вы так же должны внести изменения в записи файла /etc/fstab, для указания что теперь раздел является файловой системой "ext3". Так же вы можете использовать авто определение типа раздела (опция «auto»), но все же рекомендуется явно указывать тип файловой системы. Следующий пример файл /etc/fstab показывает изменения до и после перевода файловой системы для раздела /dev/hda5:

/dev/ hda5 /opt ext2 defaults 1 2

/dev/ hda5 /opt ext3 defaults 1 0

Последнее поле в /etc/fstab указывает этап в загрузке, во время которого целостность файловой системы должна быть проверена с помощью утилиты «fsck». При использовании файловой системы ext3, вы можете установить это значение в «0», как показано на предыдущем примере. Это означает что программа "fsck" никогда не будет проверять целостность файловой системе, в связи с тем что целостность файловой системы гарантируется путем отката в журнале.

Перевод корневой файловой системы в ext3 требует особого подхода, и лучше всего его проводить в режиме одного пользователя (single user mode) после создания RAM диска поддерживающего файловую систему ext3.

Кроме совместимости с утилитами файловой системы ext2 и простым переводом файловой системы из ext2 в ext3, файловая система ext3 так же предлагает несколько различных типов журнилирования.

Файловая система ext3 поддерживает три различных режима журналирования, которые могут быть активированы из файла /etc/fstab. Эти режимы журналирования следующие:

    Журнал / journal – запись всех изменений данных файловой системы и мета-данных. Наиболее медленный из всех трех режимов журналирования. Этот режим минимизирует шанс потери изменений файлов которые вы проводите в файловой системе.

    Последовательный / ordered – записываются изменения только мета-данных файловой системы, но записывает обновления данных файла на диск перед изменениями ассоциируемых мета-данных файловой системы. Этот режим журналирования ext3 установлен по умолчанию.

    Обратная запись / writeback – записываются только изменения мета-данных файловой системы, основан на стандартном процессе записи изменений данных файлов. Это наиболее быстрый метод журналирования.

Различия между этими режимами журналирования одновременно и едва заметны, и основательны. Использование режима «журнал» требует, что бы файловая система ext3 записывала каждое изменение файловой системы дважды – первый раз в журнал, а затем в саму файловую систему. Это может снизить общую производительность вашей файловой системы, но этот режим наиболее любим пользователями, потому что он минимизирует шанс потери изменения данных ваших файлов, так как и изменения мета - данных и изменения данный файлов записывается в журнал ext3 и может быть повторено при перезагрузке системы.

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

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

Указание журналируемого режима, используемого в ext3 файловой системе производиться в файле /etc/fstab для этой файловой системы. «Последовательный» режим используется по умолчанию, но вы можете указать различные режимы журналирования, путем изменения опций для требуемого раздела в файле /etc/fstab. Например, запись в /etc/fstab указывающая на использование режима журналирования «обратная запись» будет выглядеть следующим образом:

/dev/hda5 /opt ext3 data=writeback 1 0

    Файловая система семейства Windows NT (NTFS)

      Физическая структура NTFS

Начнем с общих фактов. Раздел NTFS, теоретически, может быть почти какого угодно размера. Предел, конечно, есть, но я даже не буду указывать его, так как его с запасом хватит на последующие сто лет развития вычислительной техники - при любых темпах роста. Как обстоит с этим дело на практике? Почти так же. Максимальный размер раздела NTFS в данный момент ограничен лишь размерами жестких дисков. NT4, правда, будет испытывать проблемы при попытке установки на раздел, если хоть какая-нибудь его часть отступает более чем на 8 Гб от физического начала диска, но эта проблема касается лишь загрузочного раздела.

Лирическое отступление. Метод инсталляции NT4.0 на пустой диск довольно оригинален и может навести на неправильные мысли о возможностях NTFS. Если вы укажете программе установки, что желаете отформатировать диск в NTFS, максимальный размер, который она вам предложит, будет всего 4 Гб. Почему так мало, если размер раздела NTFS на самом деле практически неограничен? Дело в том, что установочная секция просто не знает этой файловой системы:) Программа установки форматирует этот диск в обычный FAT, максимальный размер которого в NT составляет 4 Гбайт (с использованием не совсем стандартного огромного кластера 64 Кбайта), и на этот FAT устанавливает NT. А вот уже в процессе первой загрузки самой операционной системы (еще в установочной фазе) производится быстрое преобразование раздела в NTFS; так что пользователь ничего и не замечает, кроме странного "ограничения" на размер NTFS при установке. :)

      Структура раздела - общий взгляд

Как и любая другая система, NTFS делит все полезное место на кластеры - блоки данных, используемые единовременно. NTFS поддерживает почти любые размеры кластеров - от 512 байт до 64 Кбайт, неким стандартом же считается кластер размером 4 Кбайт. Никаких аномалий кластерной структуры NTFS не имеет, поэтому на эту, в общем-то, довольно банальную тему, сказать особо нечего.

Диск NTFS условно делится на две части. Первые 12% диска отводятся под так называемую MFT зону - пространство, в которое растет метафайл MFT (об этом ниже). Запись каких-либо данных в эту область невозможна. MFT-зона всегда держится пустой - это делается для того, чтобы самый главный, служебный файл (MFT) не фрагментировался при своем росте. Остальные 88% диска представляют собой обычное пространство для хранения файлов.

Свободное место диска, однако, включает в себя всё физически свободное место - незаполненные куски MFT-зоны туда тоже включаются. Механизм использования MFT-зоны таков: когда файлы уже нельзя записывать в обычное пространство, MFT-зона просто сокращается (в текущих версиях операционных систем ровно в два раза), освобождая таким образом место для записи файлов. При освобождении места в обычной области MFT зона может снова расширится. При этом не исключена ситуация, когда в этой зоне остались и обычные файлы: никакой аномалии тут нет. Что ж, система старалась оставить её свободной, но ничего не получилось. Жизнь продолжается... Метафайл MFT все-таки может фрагментироваться, хоть это и было бы нежелательно.

      MFT и его структура

Файловая система NTFS представляет собой выдающееся достижение структуризации: каждый элемент системы представляет собой файл - даже служебная информация. Самый главный файл на NTFS называется MFT, или Master File Table - общая таблица файлов. Именно он размещается в MFT зоне и представляет собой централизованный каталог всех остальных файлов диска, и, как не парадоксально, себя самого. MFT поделен на записи фиксированного размера (обычно 1 Кбайт), и каждая запись соответствует какому либо файлу (в общем смысле этого слова). Первые 16 файлов носят служебный характер и недоступны операционной системе - они называются метафайлами, причем самый первый метафайл - сам MFT. Эти первые 16 элементов MFT - единственная часть диска, имеющая фиксированное положение. Интересно, что вторая копия первых трех записей, для надежности (они очень важны) хранится ровно посередине диска. Остальной MFT-файл может располагаться, как и любой другой файл, в произвольных местах диска - восстановить его положение можно с помощью его самого, "зацепившись" за самую основу - за первый элемент MFT.

        Метафайлы

Первые 16 файлов NTFS (метафайлы) носят служебный характер. Каждый из них отвечает за какой-либо аспект работы системы. Преимущество настолько модульного подхода заключается в поразительной гибкости - например, на FAT-е физическое повреждение в самой области FAT фатально для функционирования всего диска, а NTFS может сместить, даже фрагментировать по диску, все свои служебные области, обойдя любые неисправности поверхности - кроме первых 16 элементов MFT.

Метафайлы находятся корневом каталоге NTFS диска - они начинаются с символа имени "$", хотя получить какую-либо информацию о них стандартными средствами сложно. Любопытно, что и для этих файлов указан вполне реальный размер - можно узнать, например, сколько операционная система тратит на каталогизацию всего вашего диска, посмотрев размер файла $MFT. В следующей таблице приведены используемые в данный момент метафайлы и их назначение.

копия первых 16 записей MFT, размещенная посередине диска

файл поддержки журналирования (см. ниже)

служебная информация - метка тома, версия файловой системы, т.д.

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

корневой каталог

карта свободного места тома

загрузочный сектор (если раздел загрузочный)

файл, в котором записаны права пользователей на использование дискового пространства (начал работать лишь в NT5)

файл - таблица соответствия заглавных и прописных букв в имен файлов на текущем томе. Нужен в основном потому, что в NTFS имена файлов записываются в Unicode, что составляет 65 тысяч различных символов, искать большие и малые эквиваленты которых очень нетривиально.

        Файлы и потоки

Итак, у системы есть файлы - и ничего кроме файлов. Что включает в себя это понятие на NTFS?

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

    Опциональный элемент - потоки данных файла. Может показаться странным определение "опциональный", но, тем не менее, ничего странного тут нет. Во-первых, файл может не иметь данных - в таком случае на него не расходуется свободное место самого диска. Во-вторых, файл может иметь не очень большой размер. Тогда идет в ход довольно удачное решение: данные файла хранятся прямо в MFT, в оставшемся от основных данных месте в пределах одной записи MFT. Файлы, занимающие сотни байт, обычно не имеют своего "физического" воплощения в основной файловой области - все данные такого файла хранятся в одном месте - в MFT.

Довольно интересно обстоит дело и с данными файла. Каждый файл на NTFS, в общем-то, имеет несколько абстрактное строение - у него нет как таковых данных, а есть потоки (streams). Один из потоков и носит привычный нам смысл - данные файла. Но большинство атрибутов файла - тоже потоки! Таким образом, получается, что базовая сущность у файла только одна - номер в MFT, а всё остальное опционально. Данная абстракция может использоваться для создания довольно удобных вещей - например, файлу можно "прилепить" еще один поток, записав в него любые данные - например, информацию об авторе и содержании файла, как это сделано в Windows 2000 (самая правая закладка в свойствах файла, просматриваемых из проводника). Интересно, что эти дополнительные потоки не видны стандартными средствами: наблюдаемый размер файла - это лишь размер основного потока, который содержит традиционные данные. Можно, к примеру, иметь файл нулевой длинны, при стирании которого освободится 1 Гбайт свободного места - просто потому, что какая-нибудь хитрая программа или технология прилепила в нему дополнительный поток (альтернативные данные) гигабайтового размера. Но на самом деле в текущий момент потоки практически не используются, так что опасаться подобных ситуаций не следует, хотя гипотетически они возможны. Просто имейте в виду, что файл на NTFS - это более глубокое и глобальное понятие, чем можно себе вообразить просто просматривая каталоги диска. Ну и напоследок: имя файла может содержать любые символы, включая полый набор национальных алфавитов, так как данные представлены в Unicode - 16-битном представлении, которое дает 65535 разных символов. Максимальная длина имени файла - 255 символов.

      Каталоги

Каталог на NTFS представляет собой специфический файл, хранящий ссылки на другие файлы и каталоги, создавая иерархическое строение данных на диске. Файл каталога поделен на блоки, каждый из которых содержит имя файла, базовые атрибуты и ссылку на элемент MFT, который уже предоставляет полную информацию об элементе каталога. Внутренняя структура каталога представляет собой бинарное дерево. Вот что это означает: для поиска файла с данным именем в линейном каталоге, таком, например, как у FAT-а, операционной системе приходится просматривать все элементы каталога, пока она не найдет нужный. Бинарное же дерево располагает имена файлов таким образом, чтобы поиск файла осуществлялся более быстрым способом - с помощью получения двухзначных ответов на вопросы о положении файла. Вопрос, на который бинарное дерево способно дать ответ, таков: в какой группе, относительно данного элемента, находится искомое имя - выше или ниже? Мы начинаем с такого вопроса к среднему элементу, и каждый ответ сужает зону поиска в среднем в два раза. Файлы, скажем, просто отсортированы по алфавиту, и ответ на вопрос осуществляется очевидным способом - сравнением начальных букв. Область поиска, суженная в два раза, начинает исследоваться аналогичным образом, начиная опять же со среднего элемента.

Вывод - для поиска одного файла среди 1000, например, FAT придется осуществить в среднем 500 сравнений (наиболее вероятно, что файл будет найден на середине поиска), а системе на основе дерева - всего около 10-ти (2^10 = 1024). Экономия времени поиска налицо. Не стоит, однако думать, что в традиционных системах (FAT) всё так запущено: во-первых, поддержание списка файлов в виде бинарного дерева довольно трудоемко, а во-вторых - даже FAT в исполнении современной системы (Windows2000 или Windows98) использует сходную оптимизацию поиска. Это просто еще один факт в вашу копилку знаний. Хочется также развеять распространенное заблуждение (которое я сам разделял совсем еще недавно) о том, что добавлять файл в каталог в виде дерева труднее, чем в линейный каталог: это достаточно сравнимые по времени операции - дело в том, что для того, чтобы добавить файл в каталог, нужно сначала убедится, что файла с таким именем там еще нет:) - и вот тут-то в линейной системе у нас будут трудности с поиском файла, описанные выше, которые с лихвой компенсируют саму простоту добавления файла в каталог.

Какую информацию можно получить, просто прочитав файл каталога? Ровно то, что выдает команда dir. Для выполнения простейшей навигации по диску не нужно лазить в MFT за каждым файлом, надо лишь читать самую общую информацию о файлах из файлов каталогов. Главный каталог диска - корневой - ничем не отличается об обычных каталогов, кроме специальной ссылки на него из начала метафайла MFT.

      Журналирование

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

Пример 1: осуществляется запись данных на диск. Вдруг выясняется, что в то место, куда мы только что решили записать очередную порцию данных, писать не удалось - физическое повреждение поверхности. Поведение NTFS в этом случае довольно логично: транзакция записи откатывается целиком - система осознает, что запись не произведена. Место помечается как сбойное, а данные записываются в другое место - начинается новая транзакция.

Пример 2: более сложный случай - идет запись данных на диск. Вдруг, бах - отключается питание и система перезагружается. На какой фазе остановилась запись, где есть данные, а где чушь? На помощь приходит другой механизм системы - журнал транзакций. Дело в том, что система, осознав свое желание писать на диск, пометила в метафайле $LogFile это свое состояние. При перезагрузке это файл изучается на предмет наличия незавершенных транзакций, которые были прерваны аварией и результат которых непредсказуем - все эти транзакции отменяются: место, в которое осуществлялась запись, помечается снова как свободное, индексы и элементы MFT приводятся в с состояние, в котором они были до сбоя, и система в целом остается стабильна. Ну а если ошибка произошла при записи в журнал? Тоже ничего страшного: транзакция либо еще и не начиналась (идет только попытка записать намерения её произвести), либо уже закончилась - то есть идет попытка записать, что транзакция на самом деле уже выполнена. В последнем случае при следующей загрузке система сама вполне разберется, что на самом деле всё и так записано корректно, и не обратит внимания на "незаконченную" транзакцию.

И все-таки помните, что журналирование - не абсолютная панацея, а лишь средство существенно сократить число ошибок и сбоев системы. Вряд ли рядовой пользователь NTFS хоть когда-нибудь заметит ошибку системы или вынужден будет запускать chkdsk - опыт показывает, что NTFS восстанавливается в полностью корректное состояние даже при сбоях в очень загруженные дисковой активностью моменты. Вы можете даже оптимизировать диск и в самый разгар этого процесса нажать reset - вероятность потерь данных даже в этом случае будет очень низка. Важно понимать, однако, что система восстановления NTFS гарантирует корректность файловой системы, а не ваших данных. Если вы производили запись на диск и получили аварию - ваши данные могут и не записаться. Чудес не бывает.

Файлы NTFS имеют один довольно полезный атрибут - "сжатый". Дело в том, что NTFS имеет встроенную поддержку сжатия дисков - то, для чего раньше приходилось использовать Stacker или DoubleSpace. Любой файл или каталог в индивидуальном порядке может хранится на диске в сжатом виде - этот процесс совершенно прозрачен для приложений. Сжатие файлов имеет очень высокую скорость и только одно большое отрицательное свойство - огромная виртуальная фрагментация сжатых файлов, которая, правда, никому особо не мешает. Сжатие осуществляется блоками по 16 кластеров и использует так называемые "виртуальные кластеры" - опять же предельно гибкое решение, позволяющее добиться интересных эффектов - например, половина файла может быть сжата, а половина - нет. Это достигается благодаря тому, что хранение информации о компрессированности определенных фрагментов очень похоже на обычную фрагментацию файлов: например, типичная запись физической раскладки для реального, несжатого, файла:

кластеры файла с 1 по 43-й хранятся в кластерах диска начиная с 400-го кластеры файла с 44 по 52-й хранятся в кластерах диска начиная с 8530-го...

Физическая раскладка типичного сжатого файла:

кластеры файла с 1 по 9-й хранятся в кластерах диска начиная с 400-го кластеры файла с 10 по 16-й нигде не хранятся кластеры файла с 17 по 18-й хранятся в кластерах диска начиная с 409-го кластеры файла с 19 по 36-й нигде не хранятся....

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

      Безопасность

NTFS содержит множество средств разграничения прав объектов - есть мнение, что это самая совершенная файловая система из всех ныне существующих. В теории это, без сомнения, так, но в текущих реализациях, к сожалению, система прав достаточно далека от идеала и представляет собой хоть и жесткий, но не всегда логичный набор характеристик. Права, назначаемые любому объекту и однозначно соблюдаемые системой, эволюционируют - крупные изменения и дополнения прав осуществлялись уже несколько раз и к Windows 2000 все-таки они пришли к достаточно разумному набору.

Права файловой системы NTFS неразрывно связаны с самой системой - то есть они, вообще говоря, необязательны к соблюдению другой системой, если ей дать физический доступ к диску. Для предотвращения физического доступа в Windows2000 (NT5) всё же ввели стандартную возможность - об этом см. ниже. Система прав в своем текущем состоянии достаточно сложна, и я сомневаюсь, что смогу сказать широкому читателю что-нибудь интересное и полезное ему в обычной жизни. Если вас интересует эта тема - вы найдете множество книг по сетевой архитектуре NT, в которых это описано более чем подробно.

На этом описание строение файловой системы можно закончить, осталось описать лишь некоторое количество просто практичных или оригинальных вещей.

Эта штука была в NTFS с незапамятных времен, но использовалась очень редко - и тем не менее: Hard Link - это когда один и тот же файл имеет два имени (несколько указателей файла-каталога или разных каталогов указывают на одну и ту же MFT запись). Допустим, один и тот же файл имеет имена 1.txt и 2.txt: если пользователь сотрет файл 1, останется файл 2. Если сотрет 2 - останется файл 1, то есть оба имени, с момента создания, совершенно равноправны. Файл физически стирается лишь тогда, когда будет удалено его последнее имя.

      Symbolic Links (NT5)

Гораздо более практичная возможность, позволяющая делать виртуальные каталоги - ровно так же, как и виртуальные диски командой subst в DOSе. Применения достаточно разнообразны: во-первых, упрощение системы каталогов. Если вам не нравится каталог Documents and settings\Administrator\Documents, вы можете прилинковать его в корневой каталог - система будет по прежнему общаться с каталогом с дремучим путем, а вы - с гораздо более коротким именем, полностью ему эквивалентным. Для создания таких связей можно воспользоваться программой junction (junction.zip(15 Kb), 36 кб), которую написал известный специалист Mark Russinovich (http://www.sysinternals.com). Программа работает только в NT5 (Windows 2000), как и сама возможность. Для удаления связи можно воспользоваться стандартной командой rd. ВНИМАНИЕ: Попытка удаления связи с помощью проводника или других файловых менеджеров, не понимающих виртуальную природу каталога (например, FAR), приведет к удалению данных, на которые ссылается ссылка! Будьте осторожны.

      Шифрование (NT5)

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

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

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

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

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

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

Файловая структура - иерархическая структура, в виде которой операционная система отображает файлы и каталоги (папки).

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

Имена внешних носителей информации. Диски, на которых хранится информация в компьютере, имеют свои имена - каждый диск назван буквой латинского алфавита, а затем ставится двоеточие. Так, для дискет всегда отводятся буквы А: и В: . Логические диски винчестера именуются, начиная с буквы С: . После всех имен логических дисков следуют имена дисководов для компакт-дисков. Например, установлены: дисковод для дискет, винчестер, разбитый на 3 логических диска и дисковод для компакт-дисков. Определить буквы всех носителей информации. А: - дисковод для дискет; С: , D: , Е: - логические диски винчестера; F: - дисковод для компакт-дисков.

Логический диск или том (англ. volume или англ. partition ) - часть долговременной памяти компьютера, рассматриваемая как единое целое для удобства работы. Термин «логический диск» используется в противоположность «физическому диску», под которым рассматривается память одного конкретного дискового носителя.

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

Помимо хранимой информации том содержит описание файловой системы - как правило, это таблица с перечислением всех файлов и их атрибутов (Таблица размещения файлов - англ. File Allocation Table, FAT). В таблице определяется, в частности, в каком каталоге (папке) находится тот или иной файл. Благодаря этому при переносе файла из одной папки в другую в пределах одного тома, не осуществляется перенос данных из одной части физического диска на другую, а просто меняется запись в таблице размещения файлов. Если же файл переносится с одного логического диска на другой (даже если оба логических диска расположены на одном физическом диске), обязательно будет происходить физический перенос данных (копирование с дальнейшим удалением оригинала в случае успешного завершения).

По этой же причине форматирование и дефрагментация каждого логического диска не затрагивает другие.

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

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

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

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

Путь к файлу - это имя носителя (диска) и последовательность имен каталогов, в ОС Windows разделенных символом «\» (в ОС линии UNIX используется символ «/»). Этот путь задает маршрут к тому каталогу, в котором находится нужный файл.

Для указания пути к файлу используют два различных метода. В первом случае каждому файлу дается абсолютное имя пути (полное имя файла), состоящее из имен всех каталогов от корневого до того, в котором содержится файл, и имени самого файла. Например, путь С:\Abby\Doc\otchet.doc означает, что корневой каталог диска С: содержит каталог Abby , который, в свою очередь, содержит подкаталог Doc , где находится файл otchet.doc . Абсолютные имена путей всегда начинаются от имени носителя и корневого каталога и являются уникальными. Применяется и относительное имя пути. Оно используется вместе с понятием текущего каталога. Пользователь может назначить один из каталогов текущим рабочим каталогом. В этом случае все имена путей, не начинающиеся с символа разделителя, считаются относительными и отсчитываются относительно текущего каталога. Например, если текущим каталогом является С:\Abby , тогда к файлу с абсолютным путем С:\Abby\ можно обратиться как Doc\otchet.doc .

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

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

Основное поисковое средство Windows XP запускают из Главного меню командой Пуск > Найти > Файлы и папки . Не менее удобен и другой вариант запуска - из любого окна папки (Вид > Панели обозревателя > Поиск > Файлы и папки или клавиша F3 ).

Локализовать сферу поиска с учетом имеющейся информации об имени и адресе файла позволяют элементы управления, представленные на панели поиска. При вводе имени файла разрешается использовать подстановочные символы «*» и «?» . Символ «*» заменяет любое число произвольных символов, а символ«?» заменяет один любой символ. Так, например, поиск файла с именем *.txt завершится с отображением всех файлов, имеющих расширение имени.txt , а результатом поиска файлов с именем *.??t станет список всех файлов, имеющих расширения имени.txt, .bat, .dat и так далее.

При поиске файлов, имеющих «длинные» имена, следует иметь в виду, что если «длинное» имя содержит пробелы (а это допустимо), то при создании задания на поиск такое имя следует заключать в кавычки, например: «Текущие paбoты.doc».

На панели поиска имеются дополнительные скрытые элементы управления. Они отображаются, если щелкнуть на раскрывающей стрелке, направленной вниз.

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

· Вопрос Какой размер файла? позволяет при поиске ограничиться файлами определенного размера.

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

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

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

19.Сжатие данных и архивация файлов.

Характерной особенностью большинства «классических» типов данных, с которыми традиционно работают люди, является определенная избыточность. Степень избыточности зависит от типа данных. Кроме того, степень избыточности данных зависит от принятой системы кодирования. Так, например, можно сказать, что кодирование текстовой информации средствами русского языка (с использованием русской азбуки) дает в среднем избыточность на 20-30% больше, чем кодирование адекватной информации средствами английского языка.
При обработке информации избыточность также играет важную роль. Однако, когда речь заходит не об обработке, а о хранении готовых документов или их передаче, то избыточность можно уменьшить, что дает эффект сжатия данных.
Если методы сжатия информации применяют к готовым документам, то нередко термин сжатие данных подменяют термином архивация данных, а программные средства, выполняющие эти операции, называют архиваторами.
В зависимости от того, в каком объекте размещены данные, подвергаемые сжатию, различают:
- уплотнение (архивацию) файлов;
- уплотнение (архивацию) папок;
- уплотнение дисков.
Если при сжатии данных происходит изменение их содержания, метод сжатия необратим и при восстановлении данных из сжатого файла не происходит полного восстановления исходной последовательности. Такие методы называют также методами сжатия с регулируемой потерей информации. Они применимы только для тех типов данных, для которых формальная утрата части содержания не приводит к значительному снижению потребительских свойств. В первую очередь, это относится к мультимедийным данным: видеорядам, музыкальным записям, звукозаписям и рисункам. Методы сжатия с потерей информации обычно обеспечивают гораздо более высокую степень сжатия, чем обратимые методы, но их нельзя применять к текстовым документам, базам данных и, тем более, к программному коду. Характерными форматами сжатия с потерей информации являются:
- JPG для графических данных;
- .MPG для видеоданных;
- . М РЗ для звуковых данных.
Если при сжатии данных происходит только изменение их структуры, то метод сжатия обратим. Из результирующего кода можно восстановить исходный массив путем применения обратного метода. Обратимые методы применяют для сжатия любых типов данных. Характерными форматами сжатия без потери информации являются:
- .GIF, TIP,. PCX и многие другие для графических данных;
- .AVI для видеоданных;
- .ZIP, .ARJ, .BAR, .LZH, .LH, .CAB и многие другие для любых типов данных.
«Классическими» форматами сжатия данных, широко используемыми в повседневной работе с компьютером, являются форматы.ZIP и.ARJ. В последнее время к ним добавился популярный формат.RAR.
К базовым функциям, которые выполняют большинство современных диспетчеров архивов, относятся:
- извлечение файлов из архивов;
- создание новых архивов;
- добавление файлов в имеющийся архив;
- создание самораспаковывающихся архивов;
- создание распределенных архивов на носителях малой емкости;
- тестирование целостности структуры архивов;
- полное или частичное восстановление поврежденных архивов;
- защита архивов от просмотра и несанкционированной модификации.
Самораспаковывающиеся архивы.. Самораспаковывающийся архив готовится на базе обычного архива путем присоединения к нему небольшого программного модуля. Сам архив получает расширение имени.ЕХЕ, характерное для исполнимых файлов.
Распределенные архивы. Некоторые диспетчеры (например WinZip) выполняют разбиение сразу на гибкие диски, а некоторые (например WinRAR и WinArj) позволяют выполнить предварительное разбиение архива на фрагменты заданного размера на жестком диске. Впоследствии их можно перенести на внешние носители путем копирования.
При создании распределенных архивов диспетчер WinZip обладает неприятной особенностью: каждый том несет файлы с одинаковыми именами. В результате этого нет возможности установить номера томов, хранящихся на каждом из гибких дисков, по названию файла Диспетчеры архивов WinArj и WinRAR маркируют все файлы распределенного архива разными именами и потому не создают подобных проблем.
Защита архивов. В большинстве случаев защиту архивов выполняют с помощью пароля, который запрашивается при попытке просмотреть, распаковать или изменить архив.
К дополнительным функциям диспетчеров архивов относятся сервисные функции, делающие работу более удобной. Они часто реализуются внешним подключением дополнительных служебных программ и обеспечивают:
- просмотр файлов различных форматов без извлечения их из архива;
поиск файлов и данных внутри архивов;
установку программ из архивов без предварительной распаковки;
проверку отсутствия компьютерных вирусов в архиве до его распаковки;
криптографическую защиту архивной информации;
декодирование сообщений электронной почты;
«прозрачное» уплотнение исполнимых файлов.ЕХЕ и.DLL;
создание самораспаковывающихся многотомных архивов;
выбор или настройку коэффициента сжатия информации.