• ベストアンサー

データファイルの行を削除する

掲示板のようなものを作っています。 データを、1投稿につき1行使って、項目を記号を使って分割させています。 1,こんにちは,umi,2004-4-1 みたいな感じですが、記事を1行削除するときの処理なのですが、 1,ファイルをロックして読み込み 2,削除する以外の行を$buffに入れる 3,rewindでポインタを先頭に 4,書き込み、ロック解除 のような処理をしているのですが、一番下の行に古いデータが残ってしまいます。 例えば 4,またあした,umi,2004-4-1 3,おはよう,umi,2004-4-1 2,さようなら,umi,2004-4-1 1,こんにちは,umi,2004-4-1 というデータの上から2行目を削除すると 4,またあした,umi,2004-4-1 2,さようなら,umi,2004-4-1 1,こんにちは,umi,2004-4-1 1,こんにちは,umi,2004-4-1 というふうになってしまいます。 通常、このような場合はどのように処理すればよろしいのでしょうか。 よろしくお願い致します。

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

  • ベストアンサー
noname#18290
noname#18290
回答No.2

$buffに書き戻すデータがあるものとして答えます。 >1,ファイルをロックして読み込み >2,削除する以外の行を$buffに入れる >3,rewindでポインタを先頭に >4,書き込み、ロック解除 4.を以下のようにします。 書き込み、ファイルサイズの切りつめ、ロック解除 ここで、サイズの切りつめには、 ftruncate($fp, strlen($buff)); とします。

umioyo
質問者

お礼

ご回答ありがとうございます。 希望通りの動きができました。 とても助かりました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • hide1978
  • ベストアンサー率42% (32/75)
回答No.1

ログが保存されているファイルを、仮にlog.datとします。 1:ファイルをロックして読み込み 2:削除する以外の行を$buffに入れる 3:$buffの内容をtmp.datに書き出し 4:log.datを削除 5:tmp.datをlog.datにリネーム ↑こんなんで如何でしょう。 各種関数に関しては参考URLを参照してください。

参考URL:
http://jp.php.net/manual/ja/ref.filesystem.php
umioyo
質問者

お礼

すいません、補足になりますが、複数のユーザーでファイルを編集する恐れがあるのですが、削除中はファイルロックできないですよね? どうすればよろしいでしょうか?

umioyo
質問者

補足

ご回答ありがとうございます。 perl/CGIでもPHPでも、すでに書き込んだファイルの行を削除するってことはできないということなのでしょうか。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ロック専用ファイルについて

    ロック専用ファイルについて すいません、またまた教えてください。m(_ _)m 一つのページに掲示板とカウンターの2つの別々のコードを含めようとしてます。 (現在、掲示板は問題なく動作していて、掲示板のコードの後に カウンターのコードを書こうとしています。) 掲示板にロック専用ファイルを作って、下記のようにしています。 $lock_fp = fopen("lock.txt", "w"); flock($lock_fp, LOCK_EX); ~掲示板ログの更新処理~ fclose($lock_fp); この後に、カウンターのコードを書いて、同じようにロック専用ファイルを使った 排他ロックの仕組みにしたいと思いましたが、そこでふと疑問が・・・。 flock()の排他ロック開始の行 ~ ロック解除の行(ロックファイルのファイルポインタ破棄の行) の間に書かれている全ての処理は、他の人がアクセスしているときは 自分の番になるまで行われないと思うのですが、 ロック解除の行の後に書かれている他のPHPの処理は普通に進んでいくのでしょうか? だとすれば、カウンター用のロック専用ファイルは 掲示板用のそれ(lock.txt)とは別のもの用意しないといけないと思うのですが、 その考え方で合っていますか? ものすごく基本的な質問な気がするのですが、参考書や参考サイトを見ても なかなか回答を上手に見つけられず困っています。 お手数ですが、ご教授ください。よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • 改行だけの行の削除

    $data1 = file_get_contents("xxxx.txt"); で、読み込んだデータの中に 「 aaaaaa bbbbbb xxxxx yyyyyy 111111 2222222 」 というレコードが入っていたとします。 この中で、改行だけの行を削除し、$data2 に移したいのです。 先頭行と最終行は、trimで削除できましたが、 $data1 = str_replace("^\\n", "", $data2); でも除去できません。 どうすればいいのか、お教えください。

    • ベストアンサー
    • 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
  • CSVファイルの最終行のデータを取り出したい

    PHPでCSVファイルのデータを取り込もうとしています。 全てのデータを表示させるのであれば、「while」などを使って書くのが一般的かと思うのですが、 最終行のデータ(「,」で区切られた最も左のフィールド)だけを取り出したいので、 以下のように書いてみました。 <?php $file = fopen("hoge.csv","a+"); $nakami = fgetcsv ($file, 1000, ","); echo $nakami[0]; fclose($file); ?> 「fopen」のmodeについて、「r」にすれば先頭から読み込まれ、 「a+」もしくは「ab+」ならばファイルの終わりにポインタが来る・・・ と色々なマニュアルに書かれていましたので、上記のようにしてみたのですが、 $nakami[0]で表示されるのは、1行目の最左列のデータになってしまいます。 1)このやり方(modeの設定)では最終行のデータ取得は不可能なのか 2)どのようなやり方なら最終行のデータ(のみ)は取得できるのか お知恵をお借りできれば幸いです。 よろしくお願いいたします。

    • 締切済み
    • PHP
  • 【マクロ】データが1つもない行を削除する

    添付した画像のようなファイルがあります。 この表の中で、データが一つもない行は削除して、上詰めにするマクロを実行したいです。 また、このシートの表は11行で終わっていますが、 他のシートは25行目で終わっていたりとバラバラです。 すべてのシートでこの処理を行いたいと思っていますので、 他のシートで処理を行ってもエラーのでないマクロを教えていただけたら幸いです。 ちなみに、 ・各シートに表はひとつづつ。 ・各シートの表の開始セルは同じ。 ・全シートに対して一気に処理を行いたい。←指定した処理をすべてのシートで行うマクロは作成済なので大丈夫です。

  • データの強制削除について

    ロックがかかっているデータを削除したいのですが、ロックが解除出来ないため削除できないでいます。普段は「情報」をみてロックのチェックを外すことで対処していたのですが、このデータだけロックの部分をいじることが出来ず所有権を変えようとすると『予期しないエラーが起きました(エラーコード120)』が表示されて変えることが出来ません。 どなたか良い方法が有りましたら教えて下さい。 OSのバージョンは10.4.11です。

    • ベストアンサー
    • Mac
  • 【PHP】csvファイルへの書き出し(1行追加or1行上書き)について

    【PHP】csvファイルへの書き出し(1行追加or1行上書き)について はじめて利用させていただきます。 現在、PHPにて書き出し処理を作成している者ですが、csvファイルへの書き出しの際に先頭行にスペースが大量に入ってしまい、困っています。 自分なりに調べてみたのですが、原因がわかりません。詳しい方からのアドバイスをお願いしたいです。 【行っている処理】 1.csvファイルを1行ずつ読み込み、配列に格納 2.既存のデータに同じ名前の人が存在する場合は、その行の配列の内容を変更(存在しない場合は配列の末尾に1件追加) 4.現在ファイルにあるデータを削除(丸めこみ)し、配列データを書き書き出し 【ソース】(書き出し処理に問題があると思ったため、それ以外の部分は割愛させていただきます) <?php $filename = 'data.csv'; $file = fopen($filename, "r+" ); $name = array(); if(flock($file,LOCK_SH)){ while( $data = fgetcsv( $file, 1000, "," ) ) {   //配列に格納 } //配列の内容変更or新規に一行追加処理 //現在のファイル内のデータを削除(まるめこみ) ftruncate($file, 0); //1行分のデータをカンマ区切りで結合し、書き出し for($i = 0; $i < $count; $i++){ $ins = $name[$i]; $ins .= ','; $ins .= $number[$i]; //書き込み失敗時のエラー if(fwrite($file, "$ins\n" ) === FALSE){ print("ファイル書き込みに失敗しました"); }else{ //処理なし } } //ファイルロック解除 flock($file, LOCK_UN); }else{ print("ファイルロックに失敗しました"); } 【csvファイルの中身(処理実行前)】 佐藤,1234 田中,12345 中村,9876 【csvファイルの中身(処理実行後)】                       佐藤,1234 田中,12345 中村,9876 以上です。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 5行おきに5行ずつ抽出するには?~教えて下さい。

    ファイル内のデータの並び替え処理したく、質問します。 データは、1列目に通し番号、2、3、4列目にデータが入っています(下に例を書きます)。 5行ごとに5つの行のデータをまとめたいのです。 具体的に言うと、「1、6、11、16、21行目」のデータをまとめて1行(タブ切り)に。新しい行には、真ん中の数字「11」を先頭列に入れたいです。 それをずらしてゆき、「2、7、12、17、21行目」のデータを1行に、、というようにしたいのです。 扱うファイルの行数は、様々です。 これを統計処理を行う予定です。perl初心者ですので、トライした思案策を載せても参考にならないかと思い、0から教えて頂く形になりますが、よろしくお願いします。 1 10 10 10 2 20 20 20 3 30 30 30 4 40 40 40 5 50 50 50 6 10 10 10 7 20 20 20 8 30 30 30 9 40 40 40 10 50 50 50 11 10 10 10 12 20 20 20 13 30 30 30 14 40 40 40 15 50 50 50 16 10 10 10 17 20 20 20 18 30 30 30 19 40 40 40 20 50 50 50 21 10 10 10 22 20 20 20 23 30 30 30 24 40 40 40 25 50 50 50 出来上がりは、 11 10 10 10 10 10 10 10 10 10 12 20 20 20 20 20 20 20 20 20 というようになります。

    • ベストアンサー
    • Perl
  • ファイルにデータを書き込むときにもとのデータを消去

    データを1個のファイルに保存しているのですが、データを更新するときに現在書き込まれている中身を一度消去してから書き込みたいのですが、どのような方法がいいのでしょうか。 $fo=@fopen($book,"r+") or die(); flock($fo, LOCK_EX); ~読み込んで書き込み用のデータ処理~ fseek($fo, 0); fwrite($fo, $buff); flock($fo, LOCK_UN); fclose($fo); と、していますが、先頭に追加されるだけで、これまでのデータが残ったままです。 一度ファイルをまっさらにするか、一度ファイルを削除して新規に作成しようかとも思いましたが、アクセス数が多くなる予定なので、あまり良い方法ではないと考えています。 このような場合、一般的にどうすればいいかご教授願えればと思います。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • ExcelVBAを使って、行の削除と削除した行の分だけ残りの行を上につめるプログラムを作りたいのですが...

    ExcelVBAを使って、行の削除と削除した行の分だけ残りの行を上につめるプログラムを作りたいのですが... 例えば、 A 1 ○ ------- B 2 ○ ------- C 3 × ------- D 4 ○ ------- E 5 × ------- F 6 × という表があったとして、コマンドボタンをクリックすると×がついている行を削除して、 A 1 ○ ------- B 2 ○ ------- D 4 ○ という風に×のあった行をつめるようなプログラムを組みたいです。 私が作ったのはループをまわす中で×を見つけるとその、下の行のセルを各々ひとつ上に上げていくというプログラムです。これだとひとつのセルごとに処理していくのでデータが多いとボタンを押してから処理が終わるまでに時間がかかってしまいます。 行をまとめて消して、その下の行を上に持ち上げる方法だと処理が早くなりそうなのですがそのプログラムがイマイチわかりません。 お分かりになるかたがいらっしゃれば、ご教授お願いします。