「覚え間違い」を教えてください!

perlで容量の大きいCSVファイルを開く方法


ファイル容量の大きいcsvファイルから、必要な項目を抜き出して別ファイルにするプログラムを作成したいと思ってます。
csvファイルが少ない場合は動作したのですが、容量が140MBを超えたデータを読み込もうとすると、ブラウザー表示で何も変化いたしません

プログラムは以下のようになってます。
-------------------------------------------------

open(IN,"$inport") || &error(" $inport を読み込みopen出来ません");
flock(IN,1);
@lines = <IN>;
foreach $lines (@lines) {
local(@val) = split("\,", $lines);
print "$val[0]";
$dat .= "$val[1]\,$val[5]\n";
}
open(OUT,">$dcsv");
flock(OUT,2);
print OUT "$dat";
close OUT;


-------------------------------------------------
件数も多いので、foreachを$lines (@lines) としないで($start .. $end)として読み込みの件数を制限して対応しようと考えてましたが、うまくいきませんでした。

ご指導いただけますと幸いです。

A 回答 (2件)

質問者さんのコードは


> @lines = <IN>;
ここで、ファイルの全データを変数に読み込んで
> foreach $lines (@lines) {
これで、データを1つづつ取り出す

という処理になっていますので、「@lines=<IN>」の時点でメモリを大量に消費します。この2行の代わりに


> while ($lines = <IN>) {

とすれば、ファイルから1行ずつデータを読んで処理するようになりますので、
ファイルサイズが大きくても処理できるようになります。

ただし、そうやったとしても、
> $dat .= "$val[1]\,$val[5]\n";
この部分で変数 $dat のサイズがどんどん大きくなりますから、そちらの分のメモリ消費は入力ファイルサイズに比例します。

---

open(IN,"$inport") || &error(" $inport を読み込みopen出来ません");
flock(IN,1);

open(OUT,">$dcsv");
flock(OUT,2);

while ($lines = <IN>) {
local(@val) = split("\,", $lines);
print "$val[0]";
print OUT "$val[1]\,$val[5]\n";
}
close IN;
close OUT;
---
とすれば、完全に入力ファイルサイズに依存しないようになります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
具体的な方法までご指導いただきとても助かりました。
早速やってみたところ無事動作いたしました。
ありがとうございます。

お礼日時:2010/06/24 22:20

foreach → whileに変更でいかがでしょうか。



foreachはファイルをすべてメモリ上に読み込みますが、
whileでは一行ごとに処理するので省メモリで済みます。
    • good
    • 0
この回答へのお礼

ありがとうございます。
早速やってみました。恐ろしいくらいのパフォーマンス向上ですね。

お礼日時:2010/06/24 22:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報