CGI-BBS > データベース > その他 > 複数CSVファイルを1つのCSVファイルにしたい。


(株)友林堂
(株)友林堂


質問者 やまあらし  投稿日 2004/4/11(日) 01:04:51
いつも参考にさせていただいています
ここの場所でいいのかどうかやや不安なのですが

今回の質問ですが 自分の都合とデータ破損防止のために 同じ項目数のCSVファイルを
1つのディレクトリに1000程保存しています。

1.csv・・・・・1000.csv と言った感じで どのファイルも項目数(コンマの数)
は同じです(100あります)
1つは500バイトほどですがファイル数は減ることはなく増え続けていきます

保守等の際に自分のPCへFTPでダウンロードしていて最近数も増えてきて
ものすごく時間がかかっています。
それで 500バイトを1000個ダウンロードするより 500Kバイト1個の
方が 遙かに早いと聞き どうにかサーバー上で1つにまとまらないかと
色々考えてはいたのですが
それぞれを読み込んで
別のファイル名を1個作り 追加保存していけばいい と言うまでは頭で分かるのですが
実際 CGIにしようとした場合


		open(A,"ファイル名") || &error('読込不可');
          何かの配列に入れないといけないのか
		close(A);


          保存までに何か加工がいるのか

		open(OUT,">" , 統一用ファイル名)||&error('書込不可');
		print OUT どのように書けばいいのか
     	close(OUT);

分からないことだらけです

今までは読みとった物を ブラウザに表示することばかりやっていたので
理屈からすればできるのだと思いやっていますが
ブラウザに表示しないで 保存していくのが全く手探りです
どなたかヒントを下されば幸いです

よろしくお願いいたします



 

プロバイダ参照:
サーバのOS:不明
パソコンのOS:Win95系
エディタ:
FTPソフト:
サーバ移転:していない
改造:(未選択)
CGI習熟度:middle

回答者 sim  [削除]  投稿日 2004/4/11(日) 19:49:48
1.opendirとreaddirなどでcsvファイル名を取得します。
2.1のファイル名を一つずつ取り出してopenする。(foreachなどで。)
3.FHをすべて配列に組み込む。push(@a,<FH>);とかでよろしいかと。
4.print OUT @a;でファイル作成。

 #!/usr/bin/perl

 opendir(DIR,"./保存されているディレクトリ");
 @log = grep { /\.csv/ } readdir(DIR);
 closedir(DIR);
 foreach(@log){
  open(FH,"./保存されているディレクトリ/$_");
  push(@a,<FH>);
  close(FH);
 }
 open(OUT,"> ./保存するディレクトリ/保存するファイル名");
 print OUT @a;
 close(OUT);

こんな感じでどうでしょうか。
間違いがあったらごめんなさい。
回答者 まさ  [削除]  投稿日 2004/4/12(月) 11:06:02
ちょっと気になることがありますので割り込ませてもらいます。

例えばファイルの数が限られていて、ひとつひとつのファイルの容量もそれほど大きく
ないのならば、simさんの方法で問題ないと思います。

質問者のやまあらしさんがおっしゃっているように
>1.csv・・・・・1000.csv と言った感じで どのファイルも項目数(コンマの数)
>は同じです(100あります)
>1つは500バイトほどですがファイル数は減ることはなく増え続けていきます

この増え続けていくというのがわたしには気になります。
今は1000ですが、これが1万、10万、100万となると、simさんのスクリプトでは問題
がおきますよね。

配列の各要素はメモリ上に保管されます。しかしその配列が大きすぎるとオーバー
フローを起こし、他のプログラムのデータ領域を破壊したり、最悪サーバが停止し
ます。

このような場合ですと、全ての値を配列に入れるのではなく、ひとつのファイルを
読み込んで、それを追加書き込みする、という作業をファイル数分繰り返す方がいい
のではないでしょうか?

スピード的にはかなり落ちますが、これならばファイルの数には影響しません。

まあ、気にしすぎと言えばそうなのですが、「ファイルが増え続ける」という箇所が
どうも気になりまして。

回答者 sim  [削除]  投稿日 2004/4/12(月) 12:35:56
なるほど。確かにそうですね。
追加書込みバージョンも書いておきます。

 #!/usr/bin/perl

 opendir(DIR,"./保存されているディレクトリ");
 @log = grep { /\.csv/ } readdir(DIR);
 closedir(DIR);
 open(OUT,">> バックアップファイルパス(日付とかのファイル名)");
 foreach(@log){
  open(FH,"./保存されているディレクトリ/$_");
  print OUT <FH>;
  close(FH);
 }
 close(OUT);

出来れば一度に全てを処理するよりは、何かを動作させたときに自動的に一つのファイルをバックアップ
なんて形にした方がよろしいかもですねー。
このやり方でも結構無茶かと思います。
質問者 やまさん  [削除]  投稿日 2004/4/17(土) 10:20:21
出張で見るのが遅くなりました

みなさま丁寧な返信ありがとうございます
何とかできたようで 調子よく動いています
でも増え続ける問題にはもう少し対応していかないと
いけないかなと思っています。

ありがとうございました

このページは終了したので返信(回答)は書きこめません
 


Web裏技