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 . See Example 10-8 for a typical use of stat that prints out a few file attributes.

Example 10-8. Obtaining file information

#include #include #include #include #include #include int main(int argc, char** argv ) { struct stat fileInfo; if (argc < 2) { std::cout << "Usage: fileinfo "; return(EXIT_FAILURE); } if (stat(argv[1], &fileInfo) != 0) { // Use stat( ) to get the info std::cerr << "Error: " << strerror(errno) << ' '; return(EXIT_FAILURE); } std::cout << "Type: : "; if ((fileInfo.st_mode & S_IFMT) == S_IFDIR) { // From sys/types.h std::cout << "Directory "; } else { std::cout << "File "; } std::cout << "Size : " << fileInfo.st_size << ' '; // Size in bytes std::cout << "Device : " << (char)(fileInfo.st_dev + 'A') << ' '; // 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 examplethis 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.

Категории