Вывод в двоичный файл обычно выполняется методом wri te(), который мы уже рассматривали, изучая вывод символов и строк. Все же обычно с его помощью выводят как раз не символы, а данные других типов. Метод имеет прототип
ostream& write(const char *str, streamsize count):
Метод записывает count символов символьного массива str в поток данных. Тип streamsize (см. п. п. 27.4.1 в [11) обычно представляет собой знаковую версию si ze_t. Никакие символы-ограничители не влияют на вывод. Метод возвращает ссылку на поток, поэтому после операции можно проверить состояние потока.
Путем преобразования указателей можно вывести в выходной двоичный поток значение переменной любого типа, например:
int i = 5;
to.write((char *)&i, sizeof(i)); TMoney d(200.56);
to.write(reinterpret_cast<char *>(&d), sizeof(TMoney)); Можно вывести и массив, например: long t[10]:
to.write((char *)&t[0], sizeof(t));
Ввод из двоичных файловых потоков делается методом read О, который имеет такой же прототип:
istream& read(char *str, streamsize count);
Метод читает count символов в символьный массив str. Размер символьного массива должен быть достаточным, чтобы вместить count символов. Метод возвращает ссылку на поток, поэтому после операции можно проверить состояние потока. Никакие символы-разделители и символы-завершители не влияют на ввод. Если обнаружен конец файла, то устанавливаются флаги eof bi t и f ai Ibi t.
Путем преобразования указателей можно ввести из входного двоичного потока значение переменной любого типа, например:
int ii; TMoney dd;
from.read((char *)&ii, sizeof(ii));
from.read(reinterpret_cast<char *>(&dd). sizeof(TMoney)); long t[10];
from.read((char *)&t[0], sizeof(t));
Существует еще один метод ввода, имеющий следующий прототип (см. п. п. 27.6.1.3 в [1]):
streamsize readsome(char *str, streamsize count);
Метод работает аналогично методу read(), но возвращает не ссылку на поток, а количество введенных символов.
Теперь легко написать программы обработки двоичных файлов. В первом примере мы создаем два двоичных файла из одного массива (листинг 14.7). Для сохранения двоичных файлов нужно создать на диске С каталог BinFiles.
Листинг 14.7. Создание и обработка двоичных файлов
#include <fstream> #include <iostream> #include <ctime> using namespace std; int main() { int m[10]={0};
srand((unsigned)time(NULL)); // инициапизация датчика случайных чисел
/* заполняем массив m числами */
for(int i = 0; i < 10; i++)
{ m[i] = rand()%10;
cout << m[i] << ' '; // контрольный вывод на экран
}
cout << '\n' ;
/* открываем файл для записи */ ofstream outstrm ("c:/binfiles/oonumberl.bin", std::ios::binary); if(outstrm.is_open())
{ for(int i =0; i < 10; i++) // выводим массив в файл поэлементно outstrm.write((char *)&m[i], sizeof(int)); outstrm.close();
}
/* открываем другой файл для записи */
outstrm.open("с:/binfiles/oonumber2.bin", std::ios::binary); if(outstrm.is_open())
{ outstrm.write((char*)m, sizeof(m)); // выводим массив в файл outstrm.close();
}
// вывод двоичного файла на экран
// открываем второй файл для чтения
{ ifstream instrm ("c:/binfiles/oonumber2.bin", std::ios::binary); int a = 0;
// читаем числа по одному из файла и выводим while(instrm.read((char *)&а, sizeof(int)))
cout << a << ' * ; cout << '\n' ;
}
// открываем первый файл для чтения
ifstream instrm ("c:/binfiles/oonumberl.bin", std::ios::binary); int t[10] = {0};
instrm.read((char *)t, sizeof(t)); // чтение файла в массив
instrm.close(); // закрываем
for(int i = 0; i < 10; i++)
cout << t [I] << ' ' ; cout << '\n' ; char ch = getchar(); return 0; }
В этом примере два двоичных файла из одного массива создаются разными способами: в файл oonumber1.bin массив выводится поэлементно, а в файл oonumber2.bin — сразу целиком одним оператором. Если мы заглянем в каталог BinFiles, то увидим, что эти два файла имеют одинаковый размер в 40 байт.
Затем те же файлы открываются как входные, читаются и выводятся на экран. Сначала открывается файл oonumber2.bin (в который мы писали массив целиком), и чтение из него выполняется по одному числу. Нетрудно вместо вывода на экран выполнять в цикле, например, суммирование чисел, записанных в этот файл.
Если вас интересует программирование Lotus или http://www.cyberforum.ru/lotus/ тогда вам на киберфорум.
Первый файл oonumber1.bin, который записывался в цикле по одному числу, читается сразу целиком в массив t одним оператором, и поток тут же закрывается. И снова мы наблюдаем на экране, что чтение выполнено совершенно правильно. Такое «смешение» для двоичных файлов безопасно, так как и в памяти, и на диске размеры данных равны si zeof (тип) п, где п — количество элементов, участвующих в обмене. |