Site hosted by Angelfire.com: Build your free website today!
 

 


 
 


 

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


Файлы на диске являются хранилищами данных. Данные записаны в виде последовательности байтов. Длинна файлов также измеряется в байтах. В терминах языка Си байт - это char.

Немного от типах данных
Хотя термин char происходит от английского character, что значит символ, буква, и действительно чаще всего в переменных типа char хранятся именно буквы, это все-таки просто числа. Напомню, что в ячейке памяти размером 1 байт (char) может храниться число от 0 до 255, без знака (unsigned char), либо от -127 до +128, если со знаком (signed char). Со знаком или без знака может быть всякий целочисленный тип (char, int, long). Примеры:
unsigned int nLength;
signed char a;
Когда не указывается со знаком или без знака переменная, то по умолчанию она со знаком. Поэтому, когда ты объявляешь массив для хранения строки char str[100], то получаешь массив для хранения чисел, которые могут быть от -127 до +128.

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

1 #include <stdio.h>

void main(){

2 FILE *f;
3 char buf[100];
4 f=fopen("c:\\autoexec.bat","rt");
5 if(f==NULL){
6 puts("Cannot open file");
7 return;

}

8 fread(buf,1,100,f);
9 fclose(f);

}



(1) для работы с файлами нужна библиотека stdio
(2) объявляем переменную, в которой будет храниться дескриптор файла. (вообще-то не сам дескриптор, но я не буду вдаваться в подробности; пока что просто пиши также и не задумывайся)
(3) объявляем массив для хранения 100 байт
(4) открываем файл c:\autoexec.bat. 2 слеша подряд - это не ошибка. Такой слеш (обратный) является спецсимволом. И чтобы он не интерпретировался, как спец символ, перед ним ставится еще один. Этот первый слеш как раз и говорит, что следующий символ не надо интерпретировать, а надо просто его включить в строку как есть. Второй параметр - это строка, определяющая способ работы с файлом. Файл можно открывать только на чтение, только на запись, на чтение и на запись и на добавление. Здесь файл открывается только на чтение. При этом после открытия текущая позиция в файле равна нулю, т.е. в самом начале файла. Еще файл можно открывать как текст (text mode) или как обычный файл (binary mode). Здесь я открываю файл как текст. Не буду вдаваться в подробности в чем разница. Просто текстовые файлы лучше открывай как текст. Нетекстовые файлы никогда не открывай как текст. И все будет ок :-) Несколько примеров: "rb" - открытие бинарного (не текстового файла) "wb+rb" - открытие бинарного файла на запись и на чтение, "at" - открытие текстового файла на добавление (append).
(5) Если файл не существует или файл занят, то функция fopen вместо дескриптора вернет NULL. Как ты можешь видеть, переменная "f" имеет тип указатель на FILE. NULL - это пустой указатель или просто ноль.
(6) Сообщаем об ошибке.
(7) И завершаем исполнение программы, выходя из функции main.
(8) Если файл был успешно открыт, то считываем из него 100 байт. Первый параметр функции fread - указатель на место в памяти, куда складывать считываемые данные. Как помнишь, просто имя массива дает указатель на начало массива (адрес памяти, где начинается массив). Второй - количество считываемых блоков, третий - размер блока. Т.е. общий объем считываемых данных - это произведение этих чисел. Последний параметр - дескриптор файла.
(9) По окончании работы с файлом закрываем его.


Пример 2
Запись строки в файл.

1 #include <stdio.h>
#include <string.h>

void main(){
FILE *f;
2 char *str="This is a sample string.";
3 f=fopen("c:\\string.txt","wt");
if(f==NULL){
puts("Cannot create file");
return;
}
4 fwrite(str,1,strlen(str),f);
fclose(f);
}


(1) подключаем библиотеку по работе с строками, чтобы использовать из нее функцию определения длины строки.
(2) Распространенный способ создания переменной, в которой бы лежала определенная строка. Создается указатель на char, который указывает на заданную строку.
(3) Открываем для записи текстовый файл. Если файл не существует, он создается. Если файл с таким именем уже существует, то он укорачивается до нуля байт. Т.е. все данные из него пропадают.
(4) Пишем файл строку. Параметр - указатель на место в памяти, где лежат данные для записи в файл, количество блоков, размер одного блока - длина строки без символа окончания строки (нуля), дескриптор файла.

Пример 3
Определение длины файла.

1 #include <stdio.h>

void main(){
FILE *f;
long nFLen;
char *strFName="c:\\command.com";

f=fopen(strFName,"rb");
if(f==NULL){
printf("Cannot open %s\n", strFName);
return;
}
fseek(f,0,SEEK_END);
2 nFLen =ftell(f);
3 fseek(f,0,SEEK_SET);
fclose(f);
printf("%s is %ld bytes\n", strFName,nFLen);
}


(1) fseek - перемещает текущую позицию в файле. Первый параметр - дескриптор файла, второй - смещение, третий - откуда считать смещение. Варианты: SEEK_SET - от начала, SEEK_CUR - от текущей позиции, SEEK_END - от конца файла. В данном случае - отступ ноль от конца файла, т.е. перемещаем текущую позицию на конец файла.
(2) Считываем чему равна текущая позиция в файле. В этот момент - она в конце файла, значит это есть размер файла.
(3) Возвращаем позицию на начало файла. В данном случае это не требуется. Но если бы мы определяли размер файла, чтобы его считать в память, то перед считыванием надо было бы обязательно вернуть текущую позицию на начало.

Вот, пожалуй, и все пока что о работе с файлами.

Задание
Написать программу копирования какого-нибудь файла (например c:\config.sys) в другое место под новым именем (например, D:\config.txt)
Для этого надо:
1. определить размер исходного файла
2. выделить необходимое количество места в памяти динамически (см. урок 5)
3. считать данные из файла в память
4. записать данные в новый файл.
5. убедиться, что созданный файл такой же, как исходный.
6. сделать эту программу с командным интерфейсом, т.е. чтобы можно было в командной строке написать: и файл c:\autoexec.bat будет скопирован в d:\text.txt


Заглавна Форум Компилатори за C++