C言語関係掲示板

過去ログ

No.130.ファイル内にあるデータの削除方法


No.766

ファイル内にあるデータの削除方法
投稿者---takeo(2002/01/10 17:47:37)


はじめまして。C言語の勉強を始めて半年になるtakeoと申します。
とても入りやすい掲示板だったので、投稿させていただきました。
現在はfopenやfcloseなどのファイル処理について勉強中です。


早速質問なのですが、ファイル内にあるデータの削除方法を教えて
もらえないでしょうか?

具体的には、あるテキストファイルの最後に数バイトだけ不必要な
データがあり、そのゴミデータを削除する方法がいまいち分かりま
せん。

fputcを使ってすべてのゴミデータの上に'\0'を上書きしてみたり、
ゴミデータの直前に'EOF'を挿入してみたのですが、データが削除
された(容量が減った)という結果にはなりませんでした。

もし何かよい方法がわかりましたら、教えて頂けないでしょうか?
よろしくお願いします。




No.767

Re:ファイル内にあるデータの削除方法
投稿者---B.Smith(2002/01/10 18:18:11)


こんにちは。

ファイルの後ろに削除したいデータがある場合、低水準入出力で関数chsizeを使ってファイルを切り詰めることができます。ただ、この関数の移植性までは確認できなかったので、とりあえずPC版ということでご紹介しておきます。
関数chsizeは、ファイルハンドルを要求しますが、ストリーム入出力でオープンしていても関数filenoによりハンドルを取得できますので、問題なく使用できます。
サンプル.
#include <io.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <stdio.h>

#define     FILENAME        "Test.txt"
#define     SIZE_DELETE     3  /* 3バイト切り詰める */

void main( void )
{
    FILE        *fp;
    int         hFile;
    long        lSize;

    /* ストリーム入出力でのオープン */
    fp = fopen(FILENAME,"r+b");
    if (!fp){
        printf("File open error.\n");
        return;
    }

    /* FILE構造体のポインタからファイルハンドルを取得 */
    hFile = _fileno(fp);

    /* 現在のファイルサイズ */
    lSize = _filelength(hFile);

    /* ファイルを切り詰める */
    _chsize(hFile,lSize - SIZE_DELETE);

    /* クローズ */
    fclose(fp);
}




No.768

ありがとうござます
投稿者---takeo(2002/01/10 18:53:20)


B.Smithさん、早速の回答ありがとうございます。
サンプルプログラムまで用意して頂きまして、大変嬉しく思います。

ところで、低水準入出力関数を使用すること事なのですが、実は今
編集しているファイル処理プログラムは、組み込み機器上で動作す
るものなのです。
よって、OSもリアルタイムOSである「μITORN」を使用しておりま
す。
(編集はLINUX上で行っています。)

低水準入出力関数については、全くの素人で詳しくは分からないの
ですが、手元にある書籍にはOSに依存する関数との事。

今回のような特殊な組み込み系OSでも動作は可能なのでしょうか?



No.770

Re:ありがとうござます
投稿者---B.Smith(2002/01/10 20:19:38)


申し訳ないのですが、μITORNはよく分かりません。ただ、入出力処理は、ストリーム操作よりも、OS(API)に近い低水準入出力の方が動く可能性があると思います。私が今まで経験してきた中では、ほとんどの場合、低水準入出力の方がサポートされていました。

蛇足ですが、組み込みでは、たとえサポートされていたとしても、標準ライブラリ(特にストリーム入出力)は極力使わない方が良いと思います(いろんな意味で無駄が多い)。
組み込みということなので、近いところでWindows CEを例にあげますが、MFCや標準ランタイムを使用するよりも、APIを直接制御した方が無駄がありません。なぜなら、これらはAPIを使用して作成されているためで、汎用性を高めるための処理が含まれるため、総合的に見てかなりの量のオーバーヘッドが発生してしまうのです。

まずは提供されているAPI、コンパイラを確認なさった方が効率良いと思います。入出力系の事はドキュメントに必ず記載するはずです。また、親切なSEならば詳細設計書に載せてくれるかもしれません。



No.773

なるほど
投稿者---takeo(2002/01/10 20:53:12)


確かに組み込みでのオーバーヘッドはできる限り避けるべきですから、
そう言う意味でも、低水準入出力は有効と言う事ですね。

まずは自分の開発環境についてもう一度調査してみます。
こういう分野は学ぶ事がたくさんありますが、ほんと面白いですね。


実は今回私が考えた方法は、ゴミデータの前までをfgetc,fputsを使って
別のファイル名でコピーし、最後に元のファイルをremove関数で削除す
るという、いかにも力技という方法を考えてました。
こんなやり方でもOKといえますか??(笑)


これからも分からない事が多々出てくると思うので、その時はまたよ
ろしくお願いします。
今回は大変貴重なアドバイスをありがとうございました。


戻る


「初心者のためのポイント学習C言語」 Last modified:2002.02.03
Copyright(c) 2000-2002 TOMOJI All Rights Reserved