Entry

プログラミングメモ - std::ifstream::read() の使い方がツライ

2009年04月09日

なんか,std::ifstream のバイナリモードでファイルの読むのが,すごくツライんですけど,気のせいだろうか。

#include <fstream>
#include <iostream>
#include <string>

static const ::size_t BUFSIZE = 1024;

int
parse(const std::string& path) {
    std::ifstream f;
    try {
        char buf[BUFSIZE];
        // open() のために例外設定
        f.exceptions(std::ios::eofbit | std::ios::failbit | std::ios::badbit);
        f.open(path.c_str(), std::ios::in | std::ios::binary);
        // read() のために例外再設定
        f.exceptions(std::ios::badbit);
        while (f.read(buf, BUFSIZE)) {
            // なんかごにょごにょ
        }
    } catch (std::ios_base::failure& e) {
        std::cerr << "file read error." << std::endl;
        return -1;
    }
    return 0;
}

バイナリモードで読み込むときは,open() するときに std::ios::binary ビットを立てて,read() で読みます。一方,std::ifstream を例外付きで読むようにするには,std::ifstream::exceptions() に投げたい例外を設定することになります。

で,open() の場合は,ファイルが見つからないとか,開けないとかいうときに,std::ios::failbit が立って,例外が投げられる。一方,read() のときは,EOF に達すると,std::ios::eofbit と std::ios::failbit が立って,例外が投げられるみたい。ただ,普通ファイルを読んでて EOF に達しただけで例外を投げたいって場合は,あまりないんじゃないかと思います。バイナリファイルのマジック(ヘッダ)を読むときくらいじゃないだろうか。

上の例のように,ファイルの内容を順次バッファに読み込んでいくような場合は,必然的に EOF に達するわけで,std::ios::eofbit が立ってると,ファイルの最後で例外が投げられちゃいます。これは困る。それだけじゃなく,EOF に達すると,std::ios::failbit も立ってしまう。これ,read() する前に送出する例外をいちいち切り替えないといかんのだろか。なんか面倒だ。つか,実質的に見ると例外が構造化されていない気がする。

バイナリを読むときって,もっとちゃんとしたやり方があるんだろうか。むふう……fread(3) 使いてぇ。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN