ファイルがC ++に存在するかどうかを確認する最良の方法は何ですか?(クロスプラットフォーム)


97

Cにファイルが存在するかどうかを確認する最良の方法何ですか?の回答を読みました(クロスプラットフォーム)、しかし標準のC ++ライブラリを使用してこれを行うより良い方法があるかどうか疑問に思っていますか?できれば、ファイルをまったく開こうとしないでください。

両方ともstataccessほとんどググできないです。#includeこれらを使用するにはどうすればよいですか?


<io.h>アクセス(実際には_accessの場合があります)。
Rob、

はい、ここから指摘されています。
c0m4 2008年

回答:


170

boost :: filesystemを使用します

#include <boost/filesystem.hpp>

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

68
シンプルなはずのことを行うために巨大なサードパーティのライブラリをインストールするのは少し面倒なようです
c0m4

89
Boostは、最終的にC ++標準ライブラリの一部となるものの多くが開発されるライブラリです。boostに関係する人々の多くは、C ++標準に関係する人々です。だから、ブーストだけではなく、任意のサードパーティのライブラリ。C ++でプログラミングしている場合、boostがインストールされているはずです。
Andreas Magnusson

ネットワーク共有に存在しないファイルに対してb :: fs :: existsが "true"を返すことを思い出しているようです: "\\ machine \ share \ this_file_doesnt_exist" => true。私がチェックした最後の時間は...ブースト1.33、使用注意していた
rlerallut

コンパイラにtr1実装が付属している場合は、Boostをインストールする必要すらありません。std :: tr1 :: filesystem
Nemanja Trifunovic

1
実際にはASFAIKはTR1を作成しませんでしたが、後の段階で追加されます。また、公式のTR1ドラフトでも参照は見つかりませんでした:open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
Andreas Magnusson

41

競合状態に注意してください。「存在する」チェックからファイルを開くまでの間にファイルが消失すると、プログラムが予期せず失敗します。

ファイルに移動してファイルを開き、エラーがないか確認し、問題がなければファイルで何かを行うことをお勧めします。セキュリティが重要なコードではさらに重要です。

セキュリティと競合状態の詳細:http : //www.ibm.com/developerworks/library/l-sprace.html


30

私はハッピーブーストユーザーであり、間違いなくAndreasのソリューションを使用します。しかし、ブーストライブラリにアクセスできなかった場合は、ストリームライブラリを使用できます。

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

実際にはファイルが開かれるため、boost :: filesystem :: existsほど良くありませんが、それでも、通常は次のことを行います。


15
ただし、このコードを使用すると、ファイルに対する権限がなくても、ファイルに対する権限がない場合はif句にジャンプします。ほとんどの場合それは重要ではありませんが、言及する価値があります。
シガー

1
与えられた引数がディレクトリを示している場合は良いが、()も真生じていることに気づいた、見stackoverflow.com/questions/9591036/...
FelixJongleur42

12

必要に応じてクロスプラットフォームである場合は、stat()を使用します。C ++標準ではありませんが、POSIXです。

MS Windowsには、_stat、_stat64、_stati64、_wstat、_wstat64、_wstati64があります。



1
NOT USING BOOSTの良い回答+1。これはやり過ぎなので、ここで提供されているものからそれを書くことは簡単ではなかったので、私は回答を投稿しました。確認してください。
gsamaras

9

いかがaccessですか?

#include <io.h>

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

io.hは、標準ではない場合でも、WindowsおよびLinuxで正常に使用できますか?
c0m4 2008年

1
access()は、Linuxで<unistd.h>を介して使用できるPOSIX関数です。
Alex B

9

もう1つの可能性はgood()、ストリームで関数を使用することです。

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

7

ファイルが存在するかどうかを調べることを再考します。代わりに、それを使用する予定の同じモードで(標準CまたはC ++で)開こうとする必要があります。たとえば、ファイルを使用する必要があるときに書き込みができない場合に、そのファイルが存在することを知っているのはどのような用途ですか?


のようlsなプログラムを書いている場合はどうなりますか?ここの元のポスターはファイルをまったく開きたくないと思います。ただし、Posixのstat関数は、ファイルの権限に関する情報を提供することになっているため、その問題は修正されます。
マイケル

6

コンパイラがC ++ 17をサポートしている場合、ブーストは必要ありません。単純に使用できます。 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

番号 必須、これはやり過ぎです。


次のように、stat()を使用しますただし、pavonによって言及されているクロスプラットフォームではありません)。

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

出力:

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...

別のバージョン(およびそれ)は、ここにあります


反対投票者ではなく、質問はクロスプラットフォームのソリューションを求めており、statはすべてのプラットフォームに存在するわけではありません。
pavon 2017

0

入力ファイルストリームクラス(ifstream)を既に使用している場合は、その関数を使用できますfail()

例:

ifstream myFile;

myFile.open("file.txt");

// Check for errors
if (myFile.fail()) {
    cerr << "Error: File could not be found";
    exit(1);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.