Существует два средства, обеспечивающие получение информации о файле. Во-первых, это структура struct
с именем stat
, которая содержит члены с информацией о файле, и, во-вторых, системный вызов (функция) с тем же самым именем, который обеспечивает получение любой запрошенной информации о файле, помещая ее в структуру stat.
stat
имеет следующий вид (из книги Кернигана (Kernigan) и Ричи (Richie) «
struct stat {
dev_t st_dev; /* устройство */
ino_t st_ino; /* номер inode */
short st_mode; /* вид */
short st_nlink /* число ссылок на файл */
short st_uid; /* пользовательский идентификатор владельца */
short st_gid; /* групповой идентификатор владельца */
dev_t st_rdev; /* для особых файлов */
off_t st_size; /* размер файла в символах */
time_t st_atime; /* время последнего доступа */
time_t st_mtime; /* время последней модификации */
time_t st_ctime; /* время последнего изменения inode */
};
Смысл каждого члена stat
зависит от ОС. Например, st_uid
и st_gid
не используются в системах Windows, в то время как в системах Unix они фактически содержат идентификаторы пользователя и группы владельца файла. Воспользуйтесь документацией ОС, чтобы узнать, какие значения поддерживаются и как они интерпретируются.
В примере 10.8 показано, как можно отображать на экране некоторые переносимые члены stat
. st_mode
содержит битовую маску, описывающую тип файла. Она позволяет узнать, является ли файл каталогом или нет. st_ size
задает размер файла в байтах. Три члена типа size_t
определяют время последнего доступа, модификации и создания файлов.
Остальные члены содержат информацию, зависящую от операционной системы. Рассмотрим st_dev
: в системах Windows этот член содержит номер устройства (дисковода) в виде смещения от буквы А, представленной в коде ASCII (именно поэтому в примере я добавляю 'A'
, чтобы получить буквенное обозначение дисковода). Но в системе Unix это будет означать нечто другое; значение этого члена передайте в системный вызов ustat
, и вы получите имя файловой системы.
Если вам требуется получить дополнительную информацию о файле, лучше всего обратиться к документации вашей ОС. Стандартные системные вызовы C-функций ориентированы на Unix, поэтому они обычно приносят больше пользы в системах Unix (и совместно с ними может использоваться ряд других системных вызовов). Если вы не используете Unix, вполне возможно, что в вашей ОС имеются поставляемые со средой разработки собственные библиотеки, которые позволяют получать более детальную информацию.
10.7. Копирование файла
Требуется скопировать файл, причем так, чтобы эта операция была переносимой, т.е. без использования зависящего от ОС программного интерфейса.
Используйте файловые потоки С++, определенные в
, для копирования одного потока в другой. Пример 10.9 показывает, как можно скопировать поток с помощью буфера
#include
#include
const static int BUF_SIZE = 4096;
using std::ios_base;
int main(int argc, char** argv) {
std::ifstream in(argv[1],
ios_base::in | ios_base::binary); // Задается двоичный режим, чтобы
std::ofstream out(argv[2], // можно было обрабатывать файлы с
ios_base::out | ios_base::binary), // любым содержимым
// Убедитесь, что потоки открылись нормально...
char buf[BUF_SIZE];
do {
in.read(&buf[0], BUF_SIZE); // Считать максимум n байт в буфер,
out.write(&buf[0], in.gcount()); // затем записать содержимое буфера
} while (in.gcount() > 0); // в поток вывода.