• ベストアンサー

fopenでディレクトリ内の全ファイルを順次開く方法

 UNIX上の/home/info/user/log内にある*.logファイルを一つずつfopenで開いて一行ずつ読み込み、用が済んだらfcloseで閉じていくようなプログラムを作りたいのですが、どうすれば良いのでしょうか?  最初はls -l /home/info/user/log/*.logをリダイレクトしたファイルリストを作り、それを読み込ませてfopen……という流れを考えていたのですが、対象となるファイルが万単位に登る為実現不可でした。  一行ずつ読み込ませる部分は既に出来ているので、fopen/fcloseに絞ってお教え下さい。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.1

お書きの方法でも別に万のファイルがあっても実現可能だと思いますが、リダイレクト先の一時ファイルを置く場所が足りないのでしょうか? 普通は、opendirして、 (readdirでディレクトリの内容を読み出してファイル名を調べfopen→処理→fclose) を繰り返します。

Zephyranthes
質問者

お礼

 lsリダイレクト実行を大量のファイルがあるディレクトリに対して行うとCPUかメモリを圧迫してしまうようで、いつまでたっても帰ってきませんでした。  opendir→readdirでで出来ました。ありがとうございます。

その他の回答 (2)

  • PED02744
  • ベストアンサー率40% (157/390)
回答No.3

ANo.1さんのおっしゃっている通りになるとおもいますよ。 ANo.1さんの回答には、参考URLが無かったので、載せておきます。 notnotさん、ごめんなさい。

参考URL:
http://www.ncad.co.jp/~komata/c-kouza14.htm
Zephyranthes
質問者

お礼

 確かにこんな形になりました。  教えていただいたやり方が正しかったと確証を持てました。ありがとうございます。

  • hosuke_dx
  • ベストアンサー率33% (4/12)
回答No.2

fopen したいファイルの名前は系統立っていますか? ファイル名が file001,file002...file10000 のようにシーケンシャル なネーミングになっているもしくはそのような ネーミングにすることが可能ならば カウンタを文字として扱い、fopen→処理→fcloseのループ内で ファイル名を作成してしまうという方法がありますよ。 そうすればファイル名一覧をテーブルとして持ったりしなくても よいのでプログラムは簡潔になります。

Zephyranthes
質問者

お礼

 使われていない番号などがあったりする為規則性はあってなきが如しでした。  ですがその発想は盲点でした。ありがとうございます

関連するQ&A

  • unix コマンドの返り値を一行にする方法について

    unix コマンドの返り値を一行にする方法について lsコマンドをリダイレクトでファイルにすると file1 file2 file3 と3行になります。 これを file1 file2 file3 の一行にしたいのですが、方法はありますか。 尚、ファイルの数は3個とは限りません。 わかる方がいらっしゃれば、教えてください。 よろしくお願いいたします。

  • fopen/fcloseでメモリリーク?

    Linux2.4系です。 Cプログラムでログファイルをフラッシュドライブ上のファイルに書き足していく処理があり、 デバッグテストで処理を高速に繰り返しながらコマンドラインのfreeコマンドでメモリ残量を 確認すると、かなり速いペースでキャッシュが減ります。 原因と対処法をご存じの方、おられないでしょうか? 処理は概ね以下のような感じです。 FILE *log_file; log_file = fopen( "../log/0001.txt" , "a+" ); fwrite( &text1, 1, sizeof(text1), log_file ); fclose( log_file ); 頻度は毎秒3回くらいで書き足すテキストは1kバイト程度です。 fwrite()を止めてもメモリ減少は止まらないですが、fopenとfclose を止めると減少しなくなります。

  • fopenでファイルを読み込み、その取り込んだファイルを置換や修正したい。

    こんばんわ。 AというファイルにBというファイルを読みこもうと思うのですがうまくいきません。 ■a.php <?php // ファイルを読み込み専用でオープンする $fp = fopen('b.php', 'r'); // 終端に達するまでループ while (!feof($fp)) { // ファイルから一行読み込む $line = fgets($fp); // 読み込んだ行を出力する print $line; // <br>の出力 print "<br>"; } // ファイルをクローズする fclose($fp); ?> ■b.php <div class="title">コンテンツ</div> <?php $amin = 1; //最小値 $amax = 4; //最大値 $randevent = rand($amin,$amax); //値を表示 if ( $randevent == 1) echo "たちつてと"; // else if ( $randevent == 2) echo "さしすせそ"; // else if ( $randevent == 3) echo "かきくけこ"; // else if ( $randevent == 4) echo "あいうえお"; ?> と、二つのファイルはこのような内容です。 もちろんincludeやリクワイヤーで取り込めばすむのでしょうが、fopenで取り込んで表示させたいのです。 このままの文章だとPHPの構文ごとHPに表記されてしまいます。 Printにしているからでしょうか? fopenでPHPの機能ごと取り込むには方法はありませんでしょうか? includeだと取り込んだ際にPHP構文の置換や修正がきかなくて困るんです。 fopenで取り込むとPHP構文を「あいうえお」の部分を「なにぬねの」にstr_replaceで置換できると思ったのです。 a.phpの中にfopenを使いb.phpの中のPHP構文を機能させる方法はありませんか?

    • ベストアンサー
    • PHP
  • ファイルをセーブする時のfopenのモードについて

    アンケートのようなシステムを作っています。 ユーザーからの投票データをログに保存するときに、 1.1行ずつ読み込む 2.データの番号とポストされた番号が一致していればデータを+1 3.変数$buffに処理が終わった行をためておく 4.1に戻る 5.全ての行が終わったらまとめて保存($buffを保存) という流れにしており、1~4はファイルロックして、読み込みおよび書き込みさせています。 例えば 3,あなたの好きな食べ物は?,0,0,0 2,あなたの好きな色は?,0,0,0 1,あなたの好きな車は?,0,0,0 というログデータがあるとして、投票フォームから渡ってきた値をforeach($_POST as $key =>$value)として $keyとログの先頭の番号が一致していれば$valueにあたるデータを+1しています。 ファイルを保存するときは $fp=@fopen($log, "w+") としていますが、これだとログデータが全部消えて0バイトになってしまいます。 $fp=@fopen($log, "r+") だと、ログデータの後に修正されたデータが追加されて保存されてしまいます。(倍のデータになってしまいます) 直前にセーブする$buffのデータを出力させると正常ですので、fopenのモードが問題だと考えています。 このような場合、どのように処理すればいいのでしょうか。 一度ファイルを消してから保存する方法も考えたのですが、ファイルをロックしながらデータを消す方法がわかりませんでした。 よろしくご教授お願い致します。

    • ベストアンサー
    • PHP
  • 自ファイル名取得(バッチファイル)

    バッチファイルで 自ファイル名の取得はどのようにすればよいでしょうか? unixのシェルでは log=$1 の用にすればよいようですので、 ためしに%1としてみましたら・・・・ループしてしまいました。

  • PHPによるファイル操作

    ファイルに格納されています一行分だけを追加変更する場合はどうしたらいいのでしょうか。 fileの内容は、 [wada] path = /home/wada writeable = yes guest ok = no max connections = 5 oplocks = True valid users = wada になっており、valid users = wada  を valid users = wada , kubo のように追加変更するプログラムの記述が、現状では、 $file = fopen("/etc/file.conf","r+"); while (!feof ($file)){      if(fgets($file, 4096) == "valid users = wada"){ if文によって取得された文字列を変更する処理(,kuboを追加する処理); } } fclose ($file); で、このvalid userd = wadaだけを引っ張り出して、追加変更する記述部分をご教授よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • ファイルを保存後リダイレクト

    こんばんは. PHPで確認ダイアログを出現させ ユーザさんにファイルを保存した後に リダイレクトを行いページの表示をかえたいのですが, ファイル保存のダイアログのところでプログラムが 止まってしまう様子でうまくリダイレクトされません. どのように記述すれば実現できるのか 教えていただけますでしょうか? よろしくお願いいたします.

    • ベストアンサー
    • PHP
  • fopenの"r+"モードで同時に読み書きする

    カンマ区切りで一行に10個のデータ(data[0]からdata[9]とする)が入っているtxtファイルがあるとします。data[]はlong型とします。 ファイルを"r+"モードで読み込み、各行で、data[0]の値によって異なる計算を行い、その結果をdata[9]の値に加えたいとおもいます。 恐らく非常に基本的なことで、申し訳ないのですが、教えていただけると助かります。。 FILE *fp; fp=fopen(fp,"test.txt","r+"); for(int i=1;i<=rowcount;i++){ //ここでdata[0]からdata[9]を読み込んだとする // data[9]+=data[0]*2;//こういう処理をする /*そして、新しいdata[9]の値をもとのdata[9]の値と置き換えたい*/ } fclose(fp);

  • FILE オープンについて

    いつもお世話になります。 今ファイルデータ検索処理を検討しております。 今、search.txtには、 検索対象となるファイルパスが記載されています。 [search.txt] /home/hoge/SAMPLE1.jpg /home/hoge/SAMPLE2.jpg search.txtをfopen()し、1行ずつfgets()して、 得られるファイルパスより、そのファイルを fopen()して解析する処理がしたいですが、 fgets()より得られたファイルパスをfopen()し、 fread()するとセグメンテーションエラーになります。 どのようにしたらいいのでしょうか? 現状のコードを下記します。 FILE *fp; char *com1 = "/home/hoge/search.txt"; FILE *confp; char buf1[1024]; char buf2[1024]; int i =0; fp = fopen(com1, "r"); while( fgets(buf1, sizeof(buf1), fp )){ confp = fopen(buf1, "rb"); //*.JPGファイルをオープン //下記fread()でセグメンテーションエラー size_t size = fread( buf2, sizeof(char), 1024, confp ); for( i = 0; i<1024; i++ ){ if( (buf2[i] == 0xff) && (buf2[i+1] == 0xe0) ){ printf("%02x\n",buf[i+5]); } } } fclose(fp); fclose(confp); 上記のように、search.txtをfopen()し、読み込んだファイルパスを fopen()して、fread()読み込みをする方法を 教えて下さい。 どうぞよろしくお願い致します。

  • 絶対パスでアーカイブされたファイルをtarコマンドの相対パスで展開

    UNIXコマンドの「tarコマンド」についての質問です。 ファイルを絶対パスを用いてアーカイブをかけた場合、アーカイブファイルの展開時に、絶対パスで展開させず相対パスで展開させる方法がわかりません。 test.logを絶対パスを用いてアーカイブします。 %pwd /export/home %ls test.log %tar -cvf test.tar /export/home/test.log %ls test.log test.tar %rm test.log %ls test.tar このアーカイブファイルを別ディレクトリに移動 %mv /export/home/test.tar /export/home/test/test.tar 自身もディレクトリ移動 %cd /export/home/test %ls test.tar このような条件でアーカイブファイルの展開を実行 %tar -xvf test.tar %ls test.tar /export/home/testのディレクトリでは展開されず下記のように 絶対パスで指定したディレクトリに展開されます。 %cd /export/home/test %ls test.log インターネットで調べたところ %tar -xvf test.tar -C /export/home/test で実行すれば相対パスで展開できると記述があったのですが うまくできませんでした。 上記のコマンドで実行したところ得にはエラーは出ず メッセージが「tar:ブロックサイズ=4」と出て展開もされませんでした。 もしよろしければご教示願えませんでしょうか。 よろしくお願いいたします。

専門家に質問してみよう