Bir dosyanın C ++ 'da olup olmadığını kontrol etmenin en iyi yolu nedir? (çapraz platform)


97

C'de bir dosya olup olmadığını kontrol etmenin en iyi yolu nedir? Sorusunun yanıtlarını okudum. (çapraz platform) , ancak bunu standart c ++ kitaplıkları kullanarak yapmanın daha iyi bir yolu olup olmadığını merak ediyorum. Tercihen dosyayı açmaya çalışmadan.

Her ikisi de statve accesshemen hemen anlaşılmaz. Bunları #includene kullanmalıyım?


Erişim için <io.h> (aslında _access olabilir).
Rob

Evet, oradan da belirtildiği gibi.
c0m4

Yanıtlar:


170

Boost :: filesystem kullanın :

#include <boost/filesystem.hpp>

if ( !boost::filesystem::exists( "myfile.txt" ) )
{
  std::cout << "Can't find my file!" << std::endl;
}

68
Basit olması gereken bir şey yapmak için büyük bir üçüncü taraf kitaplığı kurmak biraz
heyecan verici görünüyor

89
Boost, sonunda C ++ standart kitaplığının bir parçası olacak olanların çoğunun geliştirildiği bir kitaplıktır. Güçlendirme ile ilgili kişilerin çoğu, C ++ standardıyla ilgili kişilerdir. Yani boost herhangi bir üçüncü taraf kitaplığı değildir. C ++ ile programlama yapıyorsanız , boost yüklemiş olmanız gerekir !
Andreas Magnusson

B :: fs :: var'ın ağ paylaşımlarında var olmayan dosyalarda "true" döndürdüğünü hatırlıyorum: "\\ machine \ share \ this_file_doesnt_exist" => true. En son kontrol ettiğimde destek
1.33'teydi

Derleyiciniz bir tr1 uygulamasıyla gelirse, Boost'u kurmanıza bile gerek yoktur. Std :: tr1 :: dosya sisteminde olacak
Nemanja Trifunovic

1
Aslında ASFAIK TR1 yapmadı ama daha sonraki bir aşamada eklenecek. Resmi TR1 taslağında da buna herhangi bir referans bulamadım: open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
Andreas Magnusson

41

Yarış koşullarına dikkat edin: Eğer dosya "var" kontrolü ile onu açtığınız zaman arasında kaybolursa, programınız beklenmedik şekilde başarısız olacaktır.

Dosyayı gidip açmak, başarısızlığı kontrol etmek ve her şey yolundaysa dosya ile bir şeyler yapmak daha iyidir. Güvenlik açısından kritik kodla daha da önemlidir.

Güvenlik ve yarış koşulları hakkında ayrıntılar: http://www.ibm.com/developerworks/library/l-sprace.html


30

Ben mutlu bir destek kullanıcısıyım ve kesinlikle Andreas'ın çözümünü kullanacağım. Ancak, destek kitaplıklarına erişiminiz yoksa, akış kitaplığını kullanabilirsiniz:

ifstream file(argv[1]);
if (!file)
{
    // Can't open file
}

Dosya gerçekten açılacağı için boost :: filesystem :: var olduğu kadar güzel değil ... ama o zaman genellikle yapmak istediğiniz bir sonraki şey budur.


15
Ancak bu kodla, var olmasına rağmen dosya için izniniz yoksa if cümlesine de geçersiniz. Çoğu durumda önemli değildir, ancak yine de bahsetmeye değer.
scigor

1
Belirtilen bağımsız değişken bir dizini gösteriyorsa good ()
öğesinin

12

İhtiyaçlarınız için yeterince çapraz platform ise stat () kullanın. Yine de C ++ standardı değil, POSIX.

MS Windows'ta _stat, _stat64, _stati64, _wstat, _wstat64, _wstati64 vardır.


1
<sys / types.h> ve <sys / stat.h> Bkz. msdn.microsoft.com/en-us/library/14h5k7ff(VS.71).aspx
activout.se

1
BOOST KULLANMAMAK için güzel bir cevap +1 , çünkü bu bir abartıdır, ancak bunu burada verilenden yazmak önemsiz değildi, bu yüzden bir cevap gönderdim. Lütfen kontrol edin.
gsamaras

9

Nasıl olur access?

#include <io.h>

if (_access(filename, 0) == -1)
{
    // File does not exist
}

İo.h, standart olmasa bile normal olarak windows ve linux üzerinde mevcut mu?
c0m4

1
access (), Linux'ta <unistd.h> aracılığıyla kullanılabilen POSIX işlevidir.
Alex B

9

Diğer bir olasılık, good()işlevi akışta kullanmaktır:

#include <fstream>     
bool checkExistence(const char* filename)
{
     ifstream Infield(filename);
     return Infield.good();
}

7

Bir dosyanın var olup olmadığını bulmaya çalışmayı tekrar düşünürdüm. Bunun yerine, kullanmayı düşündüğünüz modda (Standart C veya C ++ 'da) açmayı denemelisiniz. Dosyanın var olduğunu bilmenin, örneğin kullanmanız gerektiğinde yazılabilir olmadığını bilmenin ne faydası var?


Ya benzer bir lsprogram yazıyorsanız ? Sanırım buradaki orijinal poster dosyayı hiç açmak istemiyor. Posix'in stat işlevinin size dosyanın izinleri hakkında bilgi vermesi gerekir, bu yüzden bu sorunu çözecektir.
Michael

6

Derleyiciniz C ++ 17'yi destekliyorsa, güçlendirmeye ihtiyacınız yoktur, basitçe kullanabilirsiniz std::filesystem::exists

#include <iostream> // only for std::cout
#include <filesystem>

if (!std::filesystem::exists("myfile.txt"))
{
    std::cout << "File not found!" << std::endl;
}

3

HAYIR ZORUNLU , ki bu aşırı bir beceri olur .


Stat () kullanın ( pavon tarafından belirtildiği gibi çapraz platform kullanmayın), şöyle:

#include <sys/stat.h>
#include <iostream>

// true if file exists
bool fileExists(const std::string& file) {
    struct stat buf;
    return (stat(file.c_str(), &buf) == 0);
}

int main() {
    if(!fileExists("test.txt")) {
        std::cerr << "test.txt doesn't exist, exiting...\n";
        return -1;
    }
    return 0;
}

Çıktı:

C02QT2UBFVH6-lm:~ gsamaras$ ls test.txt
ls: test.txt: No such file or directory
C02QT2UBFVH6-lm:~ gsamaras$ g++ -Wall main.cpp
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
test.txt doesn't exist, exiting...

Başka bir versiyon (ve o) burada bulunabilir .


Olumsuz oy veren değil, platformlar arası bir çözüm için sorulan soru ve istatistik tüm platformlarda mevcut değil.
pavon

0

Zaten girdi dosyası stream class ( ifstream) kullanıyorsanız, işlevini kullanabilirsiniz fail().

Misal:

ifstream myFile;

myFile.open("file.txt");

// Check for errors
if (myFile.fail()) {
    cerr << "Error: File could not be found";
    exit(1);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.