Focusing on C++ Files
(Page 1 of 4 )
In this third part of a five-part series on C++, you will learn how to do a variety of things with files. This article is excerpted from chapter 10 of the
C++ Cookbook, written by Ryan Stephens, Christopher Diggins, Jonathan Turkanis and Jeff Cogswell (O'Reilly; ISBN: 0596007612). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.
10.6 Getting Information About a File
Problem
You want information about a file, such as its size, device, last modification time, etc.
Solution
Use the C system call stat in <sys/stat.h>. See Example 10-8 for a typical use of stat that prints out a few file attributes.
Example 10-8. Obtaining file information
#include <iostream>
#include <ctime>
#include <sys/types.h>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
int main(int argc, char** argv )
{
struct stat fileInfo;
if (argc < 2) {
std::cout << "Usage: fileinfo <file name>\n";
return(EXIT_FAILURE);
}
if (stat(argv[1], &fileInfo) != 0) { // Use stat() to get the info
std::cerr << "Error: " << strerror(errno) << '\n';
return(EXIT_FAILURE);
}
std::cout << "Type: : ";
if ((fileInfo.st_mode & S_IFMT) == S_IFDIR) { // From sys/types.h
std::cout << "Directory\n";
} else {
std::cout << "File\n";
}
std::cout << "Size : " <<
fileInfo.st_size << '\n'; // Size in bytes
std::cout << "Device : " <<
(char)(fileInfo.st_dev + 'A') << '\n'; // Device number
std::cout << "Created : " <<
std::ctime(&fileInfo.st_ctime); // Creation time
std::cout << "Modified : " <<
std::ctime(&fileInfo.st_mtime); // Last mod time
}
Discussion
The C++ standard library supports manipulation of file content with streams, but it has no built-in support for reading or altering the metadata the OS maintains about a file, such as its size, ownership, permissions, various timestamps, and other information. However, standard C contains a number of standard system call libraries that you can use to get this kind of information about a file, and that's what Example 10-8 uses.
There are two parts to obtaining file information. First, there is a struct named stat that contains members that hold data about a file, and second there is a system call (function) of the same name, which gets information about whatever file you specify and populates a stat struct with it. A system call is a function that provides some service from the OS. A number of system calls are part of Standard C, and many of them are standardized across the different versions of Unix. The stat struct looks like this (from Kernigan and Richie’s The C Programming Language [Prentice Hall]):
struct stat {
| dev_t | st_dev; | /* device of inode */ |
| ino_t | st_ino; | /* inode number */ |
| short | st_mode; | /* mode bits */ |
| short | st_nlink; | /* number of links to file */ |
| short | st_uid; | /* owner's user id */ |
| short | st_gid; | /* owner's group id */ |
| dev_t | st_rdev; | /* for special files */ |
| off_t | st_size; | /* file size in characters */ |
| time_t | st_atime; | /* time last accessed */ |
| time_t | st_mtime; | /* time last modified */ |
| time_t | st_ctime; | /* time inode last changed */ |
| }; | |
The meaning of each of stat's members depends on the OS. For example, st_uid and st_gid mean nothing on Windows systems; whereas on Unix systems, they actually contain the user and group ids of the file's owner. Take a look at your OS documentation to see which values are supported and how to interpret them.
Example 10-8 shows how to display some of the portable members of stat.st_mode contains a bit mask describing the type of file. You can use it to determine if the file is a directory or not. st_size is the file size in bytes. The three time_t members are timestamps of the access, modification, and creation times of the files.
The remaining members contain operating-system specific information. Consider st_dev: on Windows systems, it contains the device number (drive) as an offset from ASCII letter A (which is why I add an 'A' to it in the example--this gives you the drive letter). But that won't give you the same results on Unix; pass the value returned to the ustat system call to obtain the filesystem name.
If you need more information about a file, the best thing to do is to do some investigating in your OS's documentation. The standard C system calls are Unix-centric, so they are usually more useful on Unix systems (and have a number of other system calls that can be used in conjunction with them). If you are not using Unix, chances are there are proprietary libraries that ship with your OS's development environment that provide more detailed information.
Next: 10.7 Copying a File >>
More C++ Articles
More By O'Reilly Media
|
This article is excerpted from chapter 10 of the C++ Cookbook, written by Ryan Stephens, Christopher Diggins, Jonathan Turkanis and Jeff Cogswell (O'Reilly; ISBN: 0596007612). Check it out today at your favorite bookstore. Buy this book now.
|
|