🐡

Linux では std::ifstream ではディレクトリを open できてしまうメモ

2023/04/23に公開

正確に言うと gnustl でしょうか. libc++ も同様でした.


std::ifstream ifs("./");

で開けてしまいます. badbit などは立ちません.
seekg() も OK

ちなみに MSVC ではディレクトリを渡すとエラーになります.

対策

読み込む前にディレクトリかチェック

C++ STL ではディレクトリかどうかチェックする関数はありません.
(C++17 filesystem で is_directory が実装されたが, すべての処理系でうまくいくかは不明)

stat() などでチェックします. Windows の場合は Win32 API で.

ifstream で頑張る

これも確実とはいえなさそうですが, 少なくとも gnustl, libc++ では有効.

とりあえずは peek() https://cplusplus.com/reference/istream/istream/peek/
read() で読み込んでみる.
ディレクトリの場合は error bit 立つのでそれで判定できます.

あとは, tellg() でファイルサイズを取得すると std::streampos(-1) ではななく, 0x7fffffffffffffff(std::numeric_limits<std::streamoff>::max()) が返ります.

https://stackoverflow.com/questions/4404760/processing-files-larger-than-2-gb-in-c-with-stl

これでチェックでいけるでしょう.

Discussion