WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:flockを用いてCSVファイルへ書き込みをしていますが、突然ファイルの大きさが減ってしまいます。

0:[投稿] ぴょんきち [2004/04/13 20:48 ][環境:Windows2000、IE6.0 TurboLinux、CGI、Apache、perl5.6.1]

ぴょんきちと申します。
今日は皆様のお力添えを頂きたく、書き込みさせて頂きました。

今現在、アンケートフォームを作成しています。
アンケートに登録された内容をCSVファイルに書き込んでいます。
flockを用いて、CSVファイルに書き込みをしています。
書き込みといいましても、新規のCSVファイルに関してましては、
最初に書き込みをしたあと、内容を暗号化して保管します。
(暗号化はperlのモジュールを用いています)
既存のCSVファイルに対しては、追加書き込みになりますので、
暗号されているものを1度複号化し、追加分を追記して、
再度暗号化して保管するといったやり方をしています。

現在負荷テストのために、自分のPC(クライアント)に
Microdoft社のWebApplicationSutressTool(WAS)を入れて使用しています。
負荷テストを行っている間に、ls -lコマンドで、
生成されたCSVファイルのサイズを時折見ているのですが、
突然下記のようにサイズが減り、再度増え始めるという現象が起きてしまいます。

…順調に増えていっている
29200 Apr 13 20:16 aaa.csv
29744 Apr 13 20:16 aaa.csv
31008 Apr 13 20:16 aaa.csv
1120 Apr 13 20:16 aaa.csv  →突然減ってしまった!!
1840 Apr 13 20:16 aaa.csv
2928 Apr 13 20:16 aaa.csv
3824 Apr 13 20:16 aaa.csv
…再度増え始めた

なお、ファイルの下記の書き込みは以下のように行っています。
(flockのためのモジュールとして、ソースの最初にuseでFntcl qw(:flock)を宣言しています)

#ファイルオープン・追加・クローズ
       if(open(CSV,">$csv")){
               flock(CSV,LOCK_EN);
               print CSV $encrypt;
               flock(CSV,LOCK_UN);
               close(CSV);
       }else{
           エラーログ処理記述
            }
       }

こんな状態ですと、アンケートに投稿された内容全てを見ることができません。どなたかこのような事例に対してご存知の方がいましたら、ご教授頂けたら幸いです。
よろしくお願い致します。


1:[回答] AC [2004/04/13 22:48 ]

flock(CSV,LOCK_EX);
# 排他(Exclusive)ロック


2:[回答] AC [2004/04/13 23:25 ]

>>1以外にも問題があります。

>>0 のソースではファイルの書き込みの部分だけ書かれていますが、実際に全体で行っている処理は以下のようなものでしょう(2と4の処理を行っているかどうかは不明ですが)。>>0 で提示されているのは7〜11の処理です。

1. ファイル(読み込み)オープン
(2. ファイル(共有)ロック?)
3. ファイル読み込み処理
(4. ロック解除?)
5. ファイルクローズ
6. 復号→暗号化処理
7. ファイル書き込みオープン
8. ファイル排他ロック
9. ファイル書き込み処理
10. ロック解除
11. ファイルクローズ

ここでAとBという2つのプロセスがあるとします。プロセスAがファイルの読み込みを行い、6の処理まで到達しました。そこへプロセスBが発生し、やはりファイルの読み込みを行い、6の処理まで到達しました。プロセスAが一足早く6の処理を完了し、9の処理を開始しました。さて、このあと何が起こるでしょうか。


3:[関連] AC [2004/04/13 23:34 ]

長くなって申し訳ないですが、もう一点だけ気になったので。
>暗号されているものを1度複号化し、
となっていますが、復号しようとすれば、秘密鍵をサーバに置かなければならず、暗号化の意味がないような気がします。


4:[関連] ぴょんきち [2004/04/14 11:04 ]

ACさま

ご返信ありがとうございます。
早速返信内容を参考にさせていただき、ソースを見直します。
あと>>1は、記述ミスですね。恥ずかしい…。
2>>の件は、自分で少し考えてみます。
また3>>の件ですが、まだ鍵の運用方法というのが、
設計者の中で決まっていないようで、取り合えず基本的な動きだけという話なんです。
(その基本でつまずいているプログラミング初心者のぴょんきちですが…)

では、ひとまず失礼します。


5:[関連] ぴょんきち [2004/04/14 11:09 ]

また、ACさまが2>>で記載してくださった手順ですが、
暗号化されて保存されているCSVファイルを1度複号化してから、
printを用いて追加内容を記述し、再度暗号化しますので、
6)は暗号化→複号化処理の流れになります。
すいません、返信して頂いてる立場で申し訳ないのですが…。
以上、よろしくお願いします。


6:[関連] ぴょんきち [2004/04/14 11:41 ]

ACさま

申し訳ありません。自分、勘違いしていました。
5>>は自分の間違いです。ACさまの記述で正解です。
他の処理と混同しました…。
生意気言って申し訳ありませでした。
本当にすいません。


7:[回答] バギンズ [2004/04/14 12:37 ]

読み書きするCSVを直接ロックするのではなく、
ロック専用のファイルを別に用意しておけば
ロック処理が簡単になりますよ。


8:[関連] ぴょんきち [2004/04/14 13:07 ]

バキンズさま

ご回答ありがとうございます。
ロック専用のファイルを作っておくとありますが、
どういったことでしょうか・・・?
プログラミング初心者のぴょんきちにはイメージが湧きません。
もしよろしければご説明願えませんでしょうか?
よろしくお願いします。


9:[回答] バギンズ [2004/04/14 19:25 ]

ロック専用ファイル(中身は無くてもいい)を別に用意しておき。

1.ロック専用ファイルをロック
2.CSVの読み書き処理(CSVに対してはロック不要)
3.ロック専用ファイルをアンロック

というように、ロック専用ファイルのロック/アンロックの間に
内部処理(CSVの読み書き)を挟んでおくという事です。

こうしておけば、内部処理でのファイルI/Oでは
ロックを気にしなくて済みます。


10:[回答] AC [2004/04/14 20:17 ]

この場合、アンケート結果をファイルに追加していくだけなので、最初のファイル読み込み自体が不要ではないかと。

暗号化処理をして、 open(CSV,">>$csv") でファイル追記していくだけで十分と思います。ファイル$csvへの処理はこの追記処理だけなので、ロック専用ファイルも要りません。


11:[保留] ぴょんきち [2004/04/14 22:02 ]

バキンズさま・ACさま

ご回答ありがとうございます。
バキンズさまのおっしゃるような、空のロックファイルを使った手法もありなんですね。勉強になります。

あの後考えてみましたが、もしかしたら今回はいちいち読み込んで複号化しなくても、
追加分のレコードを暗号化して、これを既存の暗号化されているないように付け足せばいいのでは…と思ったところ、
ACさまのご回答がありました。
明日辺り、この方法で実行・確認してみたいと思います。

もしかしたら、実行結果によっては再度相談させていただくかもしれません。
バキンズさま・ACさま、ありがとうございました。


12:[関連] ぴょんきち [2004/04/14 22:06 ]

バギンズさま

すいません、お名前を間違えてしまいました。
教えていただいている立場で、大変失礼をしました。
申し訳ありませんでした。


13:[質問] ぴょんきち [2004/04/15 17:41 ]

自分で実行してみました。
実行はされるものの、CSVファイル2行目以降の最初の文字の先頭に、
変な文字がついてしまいます。今はそれで苦戦しています。
自分のPCでCSVファイルを開くと、下記のように表示されます。

1行目:山田花子,,女,,23,,
2行目以降:_カp}&  孝~ウ u山田花子,,女,,23,,

といった具合です。事前に追記する1レコードだけを暗号化し、
それを追加する時にCSVファイルを開いて暗号化しています。
この最初に入ってしまうゴミ文字を何とか消して、きれいな形でCSVファイルに出力したいと思っています。
CSVファイルを改行させるのには\nが必要なので、
受け取ったパラメータをCSV形式にする際には、カンマ区切りにするようにして変数に代入しています。
下記のようにしています。
$aaa = "$name,$address,mail,$age\n";
これで$aaaにカンマ区切りの文字が入ります。
これを暗号化サブルーチンに引数で持たせ暗号化させ、
返り値で暗号化された変数を受け取ります(暗号化変数$encrypt)。
それを先日書いたようにファイルオープン→ロック→書き込み→
ロック解除→クローズという手順を踏みます。

if(open(CSV , ">>$csv")){
       flock(CSV,LOCK_EX);
       print CSV "$encrypt";
       flock(CSV,LOCK_UN);
       close(CSV);
}else{
      エラー出力処理
}

print CSV "$encrypt";の""はあってもなくても結果は同じです。
このゴミ文字をなくして、2行目以降きれいに書き込むにはどうしたらよいでしょうか?
余計な文字列か入ってしまっているようですが、何だか分かりません・・・。\nがおかしいなんて事はないだろうし・・・。
ACさま・バギンズさま、或いは、この方法をご存知の方がいらっしゃいましたら、
お力添えいただきたく思います。
よろしくお願い致します。


14:[回答] ぴょんきち [2004/04/15 17:43 ]

>といった具合です。事前に追記する1レコードだけを暗号化し、
>それを追加する時にCSVファイルを開いて暗号化しています。
は意味不明ですね。正しくは、

それを追加する時にCSVファイルを開いて追記しています。

です。すいませんでした。


15:[質問] ぴょんきち [2004/04/15 17:43 ]

回答じゃなく、質問でした・・・。
度々すいません。


16:[回答] バギンズ [2004/04/15 18:50 ]

>>10
>追記処理だけなので、ロック専用ファイルも要りません。
あぁ、そうでしたね。
でも、作ったCSVファイルの使い方に疑問が残りますが...
一旦リネームしてから使うとかですかね。

>>13
暗号化の処理を入れない場合は、思ったとおりの結果になるのでしょうか?


17:[関連] ぴょんきち [2004/04/15 19:55 ]

バギンズさま

暗号化処理を一切加えず、平分だけを追加していくだけだと、
何の問題もなく処理されます。ただ公開サーバー上に保管なので、
平分だとまずいので、暗号化する必要があります。
色々調べていますが、まだ分からず・・・。
もうお手上げ気味です(泣)
もう少し自分でも頑張ってみますが・・・。
どなたかおわかりの方は是非、ご教授くださいませ(m_m)


18:[回答] バギンズ [2004/04/15 20:39 ]

暗号化処理の問題とわかっているなら、
そこのコードだけを抜き出して動作確認すれば
いいような気がしますが、どうなのでしょう?

暗号化に使用しているモジュールが何かわからない以上は
なんとも回答できないような気が...

それと、Perlのロジック確認に↓Copalを使うという方法もあります。
http://homepage1.nifty.com/kaityo/copalpro/


19:[関連] ぴょんきち [2004/04/15 20:50 ]

暗号化に使用しているのは、crypt::CBCです。
このモジュールを用いて、暗号化処理しています。
バージョンは2.08です。
その後、改行コードがまずいのかもとも考え、
改行コードを統一してみましたが、変わりませんでした。
($aaa =~ s/\x0D\x0A|\x0D|\x0A/\n/g;としました。
$aaaには"$kanji,$kana,$address,$tel,$mail,>,$list\n"を格納してあります。)
また暗号化・複号化させるコードは、別のファイルに定義してあり、それをソースの初めでuseで呼んでいます。
なので確認しようとしても、ソースが別のところに定義してありますが、初めてこのツールを知りましたので、使い方もまだわからすです(泣)→これから見させていただきます。

改行コードの統一の仕方がまずいとかあるのでしょうか?


20:[完了] ぴょんきち [2004/04/16 11:24 ]

お世話になっております。
ぴょんきちです。

まずかったのは暗号化・複号化の処理ではなく、
やはり改行コード\nを$aaaに含ませていたことと、
複号化して平分をCSVファイルに書き込む時の処理でした。
$aaaには\nを入れず、ファイルに書き込む際に変数の後に、
\nを入れるべきでした…。

有識者の方には簡単なことであると思いますが、
基本的なことではあると思いますが、ペーペーのぴょんきちには勉強になりました。

ご回答下さったACさま・バギンズさま、ありがとうございました。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World