Запись и чтение данных в двоичном режиме
Для работы с файлом в двоичном режиме его необходимо открыть с флагом ios:: binary. Чтение и запись двоичных данных в этом режиме можно осуществлять двумя способами: · по одному байту – функции файловых потоков get () и put (); · блокам определенной длины - функции файловых потоков read () и write (). Один из вариантов прототипов функций get () и put () (чаще всего используемый) выглядит так:
ifstream & get (char & ch); ofstream & put (char ch);
Функция get () берет один символ из потока ввода, помещает его в символьный параметр ch и возвращает ссылку на поток ввода. Когда достигается конец файла, значение ссылки на поток становится равным 0. Функция put () помещает символ ch в поток вывода и возвращает ссылку на поток вывода. В следующей программе с помощью этих функций осуществляется запись в файл массива А из 5 целых чисел, чтение из файла этих данных в массив В и вывод массива В на экран:
Int main () { setlocale (0, ""); // Запись массива А в_файл "E:\test.dat" ofstream o_ File; // Создали поток вывода для записи данных в файл o_File.open ("E:\\test.dat", ios::binary); // Открыли файл if (! o_ File. is_ open()) // Проверили, удалось ли открыть файл { cout << "Открыть файл не удалось! \ n"; return 0; } // Записываем данные из массива А в файл int A[5] = {1, 2, 3, 4, 5}; char * ch = (char *) A; // ch – ссылка на массив А, как на массив символов (байт) for (int I = 0; I < sizeof(A); ++ I) o_File.put(ch[I]); o_ File. close(); // Закрываем файл // Чтение данных из_файла "E:\test.dat" в массив В; ifstream i_ File; // Создали поток ввода для чтения данных из файла i_File.open ("E:\\test.dat", ios::binary); // Открыли файл if (! i_ File. is_ open()) // Проверили, удалось ли открыть файл { cout << "Открыть файл не удалось! \ n";
return 0; } // Читаем данные из файла в массив B int B[5]; ch = (char *) B; // ch – ссылка на массив В, как на массив символов (байт) int I = 0; while (i_File) i_File.get(ch[I++]); // Предыдущий цикл можно записать короче, например, так: // while (i_File.get(*ch++); i_ File. close(); // Закрываем файл // Выводим массив В на экран for (I = 0; I < 5; ++ I) cout << B[I] << " "; cout << endl; system("pause"); return 0; }
А вот как выглядит та же программа при использовании блочных функций чтения и записи (read () и write ()) в двоичном режиме:
Int main () { setlocale (0, ""); // Запись массива А в_файл "E:\test.dat" ofstream o_ File; // Создали поток вывода для записи данных в файл o_File.open ("E:\\test.dat", ios::binary); // Открыли файл if (! o_ File. is_ open()) // Проверили, удалось ли открыть файл { cout << "Открыть файл не удалось! \ n"; return 0; } int A[5] = {1, 2, 3, 4, 5}; o_ File. write ((char *) A, sizeof (A)); // Записываем данные из массива А в файл o_ File. close (); // Закрываем файл // Чтение данных из_файла "E:\test.dat" в массив В; ifstream i_ File; // Создали поток ввода для чтения данных из файла i_File.open ("E:\\test.dat", ios::binary); // Открыли файл if (! i_ File. is_ open()) // Проверили, удалось ли открыть файл { cout << "Открыть файл не удалось! \ n"; return 0; }
int B[5]; i_ File. read ((char *) B, sizeof (B)); // Читаем данные из файла в массив B i_ File. close (); // Закрываем файл // Выводим массив В на экран for (int I = 0; I < 5; ++ I) cout << B[I] << " "; cout << endl; system("pause"); return 0; }
Функции read () и write () имеют следующие прототипы:
ifstream & read (char * buf, streamsize n); ofstream & write (const char * buf, streamsize n);
Первый параметр этих функций определяет адрес буфера (некоторого массива символов - байт) для чтения или записи данных в соответствующий файловый поток. Второй параметр задает количество символов – байт, которые необходимо взять из потока или записать в поток (тип данных streamsize – целый тип данных). Размер буфера должен соответствовать значению второго параметра.
Функция write () обеспечивает запись из буфера, адрес которого указан в первом параметре функции, n символов данных в поток вывода и возвращает ссылку на поток. Функция read () обеспечивает запись из потока ввода n символов данных в память по адресу, указанному в первом параметре buf. При достижении конца файла функция возвращает ссылку на поток, равную 0, а фактическое количество взятых из потока символов может быть меньше, чем значение n второго параметра (буфер заполнен не полностью). Фактическое количество считанных из потока ввода символов после выполнения последней операции чтения можно определить с помощью функции потока ввода gcount(). Следующий пример иллюстрирует использование функций блочного чтения и записи данных из произвольного файла.
void FileToScr (char * FileName) { fstream File (FileName, ios::in | ios::binary); if (! File) // Проверили удалось ли открыть файл { cout << "Открыть файл не удалось! \n"; return; } char Buf [1024]; do { File. read (Buf, sizeof (Buf)); // Читаем данные из файла в буфер cout. write (Buf, File. gcount ()); // Выводим содержимое буфера на экран } while (File); cout << endl; File.close (); }
Функция FileToScr () обеспечивает чтение любого указанного файла в двоичном режиме и вывод его на экран в символьном виде с использованием функций блочного чтения и записи. Этот пример показывает, что функции блочного чтения и записи применимы и к стандартным потокам cin и cout (впрочем, как и функции get () и put ()). Ключевым моментом здесь является использование функции потока ввода gcount (). С помощью этой функции удается точно определить количество символов, которое необходимо вывести на экран из буфера после очередной операции чтения из файла.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|