web-dev-qa-db-ja.com

C ++:Windowsプラットフォームでファイルの存在を確認する最良の方法

可能性のある複製:
Win32プログラムを使用してファイルが存在するかどうかを確認するにはどうすればよいですか?

ファイルの存在を確認する最良の方法は次のとおりです。

オプション1:

GetFileAttributes("C:\\MyFile.txt"); // from winbase.h
if(0xffffffff == GetFileAttributes("C:\\MyFile.txt"))
{
    //File not found
}

オプション2:

std::string fileName("C:\\MyFile.txt" );
ifstream fin( fileName.c_str() );

if( fin.fail() )
{
    //File not found
}

また、オプション1がより良い方法であると思われる場合は、0xffffffffを定数として定義する方法を教えてください(#defineを使用したくない)

ありがとう

15

GetFileAttributes()は、存在しないこと以外の理由(アクセス許可の問題など)で失敗する場合があることに注意してください。エラーコードに堅牢性のチェックを追加します。

GetFileAttributes("C:\\MyFile.txt"); // from winbase.h
if(INVALID_FILE_ATTRIBUTES == GetFileAttributes("C:\\MyFile.txt") && GetLastError()==ERROR_FILE_NOT_FOUND)
{
    //File not found
}
18
zdan

ここで考慮すべき点が2つあります。

  1. その属性を介してファイルが存在するかどうかを確認すると、潜在的に何桁も速くなります-ファイルが「遅い」ファイルシステム(テープ、ネットワークストレージ、CDなど)に存在する場合、ファイルを開くと、ファイルの場所への実際の往復が必要になります。一方、ファイル属性は、ディレクトリが照会されると、ファイルシステムドライバーによってクエリおよびキャッシュされるため、ファイル属性の調査には、一時的なディレクトリ列挙コストが含まれます。ファイルをチェックしています。

  2. ただし、files属性は、呼び出しが行われたときにファイルが存在していたことを示すだけです。ファイルを削除するか、ファイルにアクセスする権限がない可能性があります。とにかくファイルを開こうとする場合は、ファイル属性のチェックを省略して、実際にファイルを開こうとすることをお勧めします。

8
Chris Becke

Windowsのみをターゲットにしている場合、オプション#1は明らかに2つのうちの方が優れています。また、探している定数は、Windowsヘッダーに既に存在しています-INVALID_FILE_ATTRIBUTESと呼ばれています。

5
casablanca

ブーストはどうですか?

if (!boost::filesystem::exists("C:\\MyFile.txt"))
{
    ...
}

http://www.boost.org/doc/libs/1_43_0/libs/filesystem/doc/index.htm

5
Inverse

onlyファイルが存在するかどうかを確認する強力な方法は、ファイルを開いて、成功するか失敗するかを確認することです。

任意他の方法は潜在的な競合状態です。たとえば、GetFileAttributesは、ファイルが存在したかどうかを示します関数を呼び出したときですが、それを開こうとしたときに存在したかどうかとは異なります。それまでに削除(または作成)された可能性があります。

4
jalf

最初の方がいいです。 2番目は、ファイルを開くことができるかどうかを確認しますが、ファイルを開く権限がない場合でもファイルが存在する可能性があります。

INVALID_FILE_ATTRIBUTES 絶え間ない。

3
GolezTrol

文字列がディレクトリではないことも確認します。

DWORD attr = GetFileAttributes(file);
if(attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY))
    return false;   //  not a file
return true;
2
sean e

プラットフォームに依存しないため、iostreamを使用することを選択します。確かに、Windowsのみをターゲットにしている可能性がありますが、プラットフォームに依存しないライブラリを使用することは決して悪いことではありません。大規模なプロジェクトを構築している場合、次のフェーズで何が必要になるかはわかりません。

上記のコードがファイルの存在を確認するための最良の(または正しい)方法であるかどうかはわかりません。試してみてください this

ifstream f;
f.open(str);

if (f.is_open()) {
  // read file
}

昔は、OpenFileしかありませんでした(そして、私たちはすばらしかった)

OFSTRUCT of = {0};
of.cBytes = sizeof(of);

HFILE hf = ::OpenFile("c:\\windows\\write.exe",&of,OF_EXIST);

if(hf > 0)
    printf("file exists"); 

return 0;
2
weloytty

そのためのナイスシェルユーティリティ関数 PathFileExists があります。

2
Ofek Shilon
#include <iostream>
#include <windows.h>
using namespace std;

bool FileExists(const TCHAR *fileName)
{
    DWORD       fileAttr;

    fileAttr = GetFileAttributes(fileName);
    if (0xFFFFFFFF == fileAttr && GetLastError()==ERROR_FILE_NOT_FOUND)
        return false;
    return true;
}

int main(int argc, char *argv[])
{


    if ( FileExists("testtt.txt"))
    {
      cout << "File exists \n";
    }
    else
    {
        cout << "File does not exist \n";

    }


  return 0;
}
0