Domanda

Come posso verificare in C ++ se un file è un file normale (e non è una directory, una pipe, ecc.)? Ho bisogno di una funzione isFile ().

DIR *dp;
struct dirent *dirp;

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

Ho provato a confrontare dirp- > d_type con (unsigned char) 0x8, ma non sembra portatile attraverso sistemi diversi.

È stato utile?

Soluzione

È necessario chiamare stat (2) sul file, quindi utilizzare la macro S_ISREG su st_mode.

Qualcosa di simile (adattato da questa risposta ):

#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
}

Altri suggerimenti

Puoi utilizzare la boost portatile :: filesystem (la libreria C ++ standard non avrebbe potuto farlo fino alla recente introduzione di 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;
    }
}

Il C ++ stesso non si occupa dei file system, quindi non esiste un modo portatile nella lingua stessa. Esempi specifici della piattaforma sono stat per * nix (come già notato da Martin v. Löwis) e GetFileAttributes per Windows.

Inoltre, se non sei allergico a Boost , c'è abbastanza boost multipiattaforma :: filesystem .

In C ++ 17, è possibile utilizzare std :: filesystem :: is_regular_file

#include <filesystem> // additional include

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

Notare che la versione precedente di C ++ potrebbe averlo avuto sotto std :: sperimentale :: filesystem (Fonte: http://en.cppreference.com/w/cpp/filesystem/is_regular_file )

Grazie a tutti per l'aiuto, ho provato con

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

E funziona benissimo. =)

#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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top