2011-01-11 8 views
0

私はperlを使い慣れていて、perlのcsvファイルを読み書きしようとしています。しかし、問題はどこにあるのかわからないことがあります。私は '<'を使用しても問題なく読むことができますが、書き込めません。 +>>モードでファイルを開くファイルの読み取りと書き込みの両方を行います。

use strict; 
use warnings; 
use Text::CSV_XS; 

my $file = 'file.csv';  
my $csv = Text::CSV_XS->new(); 

open (InCSV, '+>>', $file) or die $!; 
while (<InCSV>) { 
    if ($csv->parse($_)) { 
     my @columns = $csv->fields(); 
     if($columns[1] eq "01") { 
       my $str = "Selected $columns[6] \n "; 
       push(@columns,$str); 

       print InCSV join("," , @columns), "\n"; 
     }     
    } else { 
     my $err = $csv->error_input; 
     print "Failed to parse line: $err"; 
    } 
} 
close InCSV; 

答えて

10

ファイルの末尾に努めてまいりますので、あなたseekない限り、バックファイルの先頭(または中央)に読み出さには何も存在しません。ファイルの先頭にあるファイルカーソルを読み取り/書き込みモードで開くには、+<モードを使用します。

つまり、おそらくこの問題に対するあなたのアプローチを再考したいと思うでしょう。データの行を読み込んで変更し、ファイルに書き戻そうとしているようです。しかし、あなたがやったやり方では、読み込んだ行ではなく次の行を上書きしています。とにかく新しいデータは古いデータよりも長くなります(バイト数が増えます)。これは確実にあなたのデータファイルを破壊することです。

いくつかのより良いアプローチは、

  • 読み取りおよびプロセスのすべてのデータを最初に、そして近くになると、あなたがそれを処理している間、一時ファイルに処理されたデータで

  • 書き込みデータを入力が上書きされることがあります入力を一時ファイルで上書きします(perlインタプリタのin-place editing modeも参照してください)

  • Tie::Fileのようなモジュールを使用して、行ベースのI/Oを処理します。このタスク

+0

私は+を使用して書いているときに<コンソールが書いているときに固まっています。もう一つは、すべての行を修正したくないということです。私は条件が満たされている特定の行だけに書きたいと思う。だから、異なるファイルへの書き込みや保存が問題になるでしょう。より良い方法がありますか? – mousey

+4

一般に、(1)変更されたデータが元のデータとまったく同じサイズであるか、または(2)変更するデータがファイルの最後にある場合に、その場でデータを変更できます。そうしないと、データが破損します。 まだ、あなたはかなり典型的な仕事をしているようです。なぜ典型的なソリューションを使用しないのですか?処理したデータをメモリまたは一時ファイルに保存してから、入力ファイルを上書きします。 – mob

+0

ここでの誤解は、読み書きを区別することだと思います。 open(3)と '<'でopenされたように、ハンドラを読み込んで閉じます。データを処理します。 '>'または '>>'でもう一度(3)を開いて書き込みます。 –

関連する問題