0

非常に巨大なcsvファイルがあり、選択クエリを使用して平均を取得する必要があります...メモリ不足のため、通常は行ごとに読み取ることはできません。

次のコードは、短い csv ファイルではうまく機能しますが、巨大なファイルでは機能しません。このコードを編集して、大きな csv ファイルに使用できるようにしていただければ幸いです。

import java.io.File;

import java.io.FileNotFoundException;
import java.util.Scanner;


public class Mu {
    public void Computemu()
    {
        String filename="testdata.csv";
        File file=new File(filename);
        try {
            Scanner inputstream=new Scanner(file);//Scanner read only string 
            // String data=inputstream.next();//Ignore the first line(header)
            double sum=0;
            double numberOfRating=0;

            while (inputstream.hasNext())
            {                       
               String data=inputstream.next();//get a whole line
                String[] values= data.split(";");//values separate by;
                double rating=Double.parseDouble(values[2].replaceAll("\"", ""));//change value to string
                if(rating>0)//do not consider implicit ratings
                {
                    sum+=rating;
                    numberOfRating++;
                }
            }
            inputstream.close();
            System.out.println("Mu is"+ (sum/numberOfRating));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
4

2 に答える 2

2

useDelimiterを呼び出さなかったので、next()空白 (デフォルトの区切り文字) がない場合、メソッドはファイル全体を文字列にロードする必要があります。

これにより、OutOfMemory エラーが発生します。

スキャナーを使用する場合は、必要に応じて区切り文字を設定してください。

ただし、CSV ライブラリ ( csvfileなど) の方がおそらく効率的です。

于 2012-07-03T19:35:02.753 に答える
0

このユースケースでは、Apache Commons FileUtil を使用することをお勧めします。これは質問で探しているものではないかもしれませんが、再実装するよりも FileUtil を使用することをお勧めします。

具体的にはlineIteratorメソッドを見てください。

于 2012-07-03T19:29:58.870 に答える