642 Stimmen

Der schnellste Weg, um zu prüfen, ob eine Datei mit Standard-C++/C++11,14,17/C existiert?

Ich möchte den schnellsten Weg finden, um zu prüfen, ob eine Datei in Standard C++11, 14, 17 oder C existiert. Ich habe Tausende von Dateien und bevor ich etwas mit ihnen mache, muss ich prüfen, ob sie alle existieren. Was kann ich anstelle von /* SOMETHING */ in der folgenden Funktion?

inline bool exist(const std::string& name)
{
    /* SOMETHING */
}

28voto

Viktor Liehr Punkte 483

Ohne andere Bibliotheken zu verwenden, verwende ich gerne den folgenden Codeschnipsel:

#ifdef _WIN32
   #include <io.h> 
   #define access    _access_s
#else
   #include <unistd.h>
#endif

bool FileExists( const std::string &Filename )
{
    return access( Filename.c_str(), 0 ) == 0;
}

Dies funktioniert plattformübergreifend für Windows und POSIX-kompatible Systeme.

25voto

Ramon La Pietra Punkte 589

Wie von PherricOxide vorgeschlagen, aber in C

#include <sys/stat.h>
int exist(const char *name)
{
  struct stat   buffer;
  return (stat (name, &buffer) == 0);
}

13voto

hungptit Punkte 1244

Ich brauche eine schnelle Funktion, die prüfen kann, ob eine Datei vorhanden ist oder nicht, und PherricOxides Antwort ist fast das, was ich brauche, außer dass sie nicht die Leistung von boost::filesystem::exists und open-Funktionen vergleicht. Aus den Benchmark-Ergebnissen können wir leicht erkennen, dass :

  • Die Verwendung der stat-Funktion ist der schnellste Weg, um zu prüfen, ob eine Datei vorhanden ist. Beachten Sie, dass meine Ergebnisse mit denen der Antwort von PherricOxide übereinstimmen.

  • Die Leistung der Funktion boost::filesystem::exists kommt der der Funktion stat sehr nahe, und sie ist auch portabel. Ich würde diese Lösung empfehlen, wenn die boost-Bibliotheken über Ihren Code zugänglich sind.

Die Benchmark-Ergebnisse wurden mit Linux-Kernel 4.17.0 und gcc-7.3 erzielt:

2018-05-05 00:35:35
Running ./filesystem
Run on (8 X 2661 MHz CPU s)
CPU Caches:
  L1 Data 32K (x4)
  L1 Instruction 32K (x4)
  L2 Unified 256K (x4)
  L3 Unified 8192K (x1)
--------------------------------------------------
Benchmark           Time           CPU Iterations
--------------------------------------------------
use_stat          815 ns        813 ns     861291
use_open         2007 ns       1919 ns     346273
use_access       1186 ns       1006 ns     683024
use_boost         831 ns        830 ns     831233

Nachstehend finden Sie meinen Benchmark-Code:

#include <string.h>                                                                                                                                                                                                                                           
#include <stdlib.h>                                                                                                                                                                                                                                           
#include <sys/types.h>                                                                                                                                                                                                                                        
#include <sys/stat.h>                                                                                                                                                                                                                                         
#include <unistd.h>                                                                                                                                                                                                                                           
#include <dirent.h>                                                                                                                                                                                                                                           
#include <fcntl.h>                                                                                                                                                                                                                                            
#include <unistd.h>                                                                                                                                                                                                                                           

#include "boost/filesystem.hpp"                                                                                                                                                                                                                               

#include <benchmark/benchmark.h>                                                                                                                                                                                                                              

const std::string fname("filesystem.cpp");                                                                                                                                                                                                                    
struct stat buf;                                                                                                                                                                                                                                              

// Use stat function                                                                                                                                                                                                                                          
void use_stat(benchmark::State &state) {                                                                                                                                                                                                                      
    for (auto _ : state) {                                                                                                                                                                                                                                    
        benchmark::DoNotOptimize(stat(fname.data(), &buf));                                                                                                                                                                                                   
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_stat);                                                                                                                                                                                                                                          

// Use open function                                                                                                                                                                                                                                          
void use_open(benchmark::State &state) {                                                                                                                                                                                                                      
    for (auto _ : state) {                                                                                                                                                                                                                                    
        int fd = open(fname.data(), O_RDONLY);                                                                                                                                                                                                                
        if (fd > -1) close(fd);                                                                                                                                                                                                                               
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_open);                                  
// Use access function                                                                                                                                                                                                                                        
void use_access(benchmark::State &state) {                                                                                                                                                                                                                    
    for (auto _ : state) {                                                                                                                                                                                                                                    
        benchmark::DoNotOptimize(access(fname.data(), R_OK));                                                                                                                                                                                                 
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_access);                                                                                                                                                                                                                                        

// Use boost                                                                                                                                                                                                                                                  
void use_boost(benchmark::State &state) {                                                                                                                                                                                                                     
    for (auto _ : state) {                                                                                                                                                                                                                                    
        boost::filesystem::path p(fname);                                                                                                                                                                                                                     
        benchmark::DoNotOptimize(boost::filesystem::exists(p));                                                                                                                                                                                               
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_boost);                                                                                                                                                                                                                                         

BENCHMARK_MAIN();

10voto

LOLOLOL Punkte 125
inline bool exist(const std::string& name)
{
    ifstream file(name);
    if(!file)            // If the file was not found, then file is 0, i.e. !file=1 or true.
        return false;    // The file was not found.
    else                 // If the file was found, then file is non-0.
        return true;     // The file was found.
}

7voto

Praveen Kumar Punkte 143

Sie können auch Folgendes tun bool b = std::ifstream('filename').good(); . Ohne die Verzweigungsanweisungen (wie if) muss es schneller gehen, da es tausende Male aufgerufen werden muss.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X