How do i check if a file is a regular file?

How do i check in C++ if a file is a regular file (and is not a directory, a pipe, etc.)? I need a function isFile().

DIR *dp;
struct dirent *dirp;

while ((dirp = readdir(dp)) != NULL) {
if ( isFile(dirp)) {
     cout << "IS A FILE!" << endl;
i++;
}

I've tried comparing dirp->d_type with (unsigned char)0x8, but it seems not portable through differents systems.

Answers


You need to call stat(2) on the file, and then use the S_ISREG macro on st_mode.

Something like (adapted from this answer):

#include <sys/stat.h>

struct stat sb;

if (stat(pathname, &sb) == 0 && S_ISREG(sb.st_mode))
{
    // file exists and it's a regular file
}

You can use the portable boost::filesystem (The standard C++ library could not have done this up until recent introduction of std::filesystem in C++17):

#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <iostream>

int main() {
    using namespace boost::filesystem;

    path p("/bin/bash");
    if(is_regular_file(p)) {
        std::cout << "exists and is regular file" << std::endl;
    }
}

C++ itself doesn't deal with file systems, so there's no portable way in the language itself. Platform-specific examples are stat for *nix (as already noted by Martin v. Löwis) and GetFileAttributes for Windows.

Also, if you're not allergic to Boost, there's fairly cross-platform boost::filesystem.


In C++17, you may use std::filesystem::is_regular_file

#include <filesystem> // additional include

if(std::filesystem::is_regular_file(yourFilePathToCheck)) 
    ; //Do what you need to do

Note that earlier version of C++ may have had it under std::experimental::filesystem (Source: http://en.cppreference.com/w/cpp/filesystem/is_regular_file)


Thank you all for the help, i've tried with

while ((dirp = readdir(dp)) != NULL) { 
   if (!S_ISDIR(dirp->d_type)) { 
        ... 
        i++; 
   } 
} 

And it works fine. =)


#include <boost/filesystem.hpp>

bool isFile(std::string filepath)
{
    boost::filesystem::path p(filepath);
    if(boost::filesystem::is_regular_file(p)) {
        return true;
    }
    std::cout<<filepath<<" file does not exist and is not a regular file"<<std::endl;
    return false;
}

Need Your Help

How to check if an uploaded file is an image without mime type?

php image-processing file-upload upload mime-types

I'd like to check if an uploaded file is an image file (e.g png, jpg, jpeg, gif, bmp) or another file. The problem is that I'm using Uploadify to upload the files, which changes the mime type and g...