C言語入門(51) 実際にプログラムを読んで理解を深めよう tail編(6)

Posted: 2013年08月01日

前回は、行単位での読み込み処理を見ました。
今回は、行単位での読み込み処理です。

foward.c rlines関数

プログラムプログラム:

/*
 * rlines -- display the last offset lines of the file.
 */
static void
rlines(FILE *fp, const char *fn, off_t off, struct stat *sbp)
{
    struct mapinfo map;
    off_t curoff, size;
    int i;

    if (!(size = sbp->st_size))
        return;
    map.start = NULL;
    map.fd = fileno(fp);

    /*
     * Last char is special, ignore whether newline or not. Note that
     * size == 0 is dealt with above, and size == 1 sets curoff to -1.
     */
    curoff = size - 2;
    while (curoff >= 0) {
        if (curoff < map.mapoff && maparound(&map, curoff) != 0) {
            ierr(fn);
            return;
        }
        for (i = curoff - map.mapoff; i >= 0; i--)
            if (map.start[i] == 'n' && --off == 0)
                break;
        /* `i' is either the map offset of a 'n', or -1. */
        curoff = map.mapoff + i;
        if (i >= 0)
            break;
    }
    curoff++;
    if (mapprint(&map, curoff, size - curoff) != 0) {
        ierr(fn);
        exit(1);
    }

    /* Set the file pointer to reflect the length displayed. */
    if (fseeko(fp, sbp->st_size, SEEK_SET) == -1) {
        ierr(fn);
        return;
    }
    if (map.start != NULL && munmap(map.start, map.maplen)) {
        ierr(fn);
        return;
    }
}

解説解説:

maparound関数でファイルのデータをメモリー展開します。
この関数では、特定サイズのバッファを読み込むため
offset分移動するまでループします。

offsetまで移動したら
mapprint関数でoffsetから末端までを表示します。

最後に、リソースの解放を行なっています。

lines関数もあり
おそらく正常に動作するとは思いますが
この関数を用意した理由として
ファイルの場合は、バイト読み込みよりも
バッファで読み込んだほうが効率的なため用意したと思われます。

カテゴリー: プログラム, 入門 | タグ: , , | コメント無し »

コメント