2013-11-04 12 views
5

ファイルアップロード機能を備えたSpring MVCアプリケーションがあります。ファイルは、InputStreamを簡単に取得できるMultipartFileとしてコントローラに渡されます。私はCSVを含むzipファイルをアップロードしています。私は、CSVを開いて一度に1行ずつ読む方法を見つけるのに苦労しています。固定サイズのバッファに読み込むネットにはたくさんの例があります。私はこれを試してみたが、バッファが非常にうまく連結していないと、それはすぐに同期しなくなると、大量のメモリを使用しています。一度にzipファイルからCSVを読み込む

 ZipEntry entry = input.getNextEntry(); 

     while(entry != null) 
     { 
      if (entry.getName().matches("Data/CSV/[a-z]{0,1}[a-z]{0,1}.csv")) 
      { 
       final String fullPath = entry.getName(); 
       final String filename = fullPath.substring(fullPath.lastIndexOf('/') + 1); 

       visitor.startFile(filename);      

       final StringBuilder fileContent = new StringBuilder(); 

       final byte[] buffer = new byte[1024];     

       while (input.read(buffer) > 0) 
        fileContent.append(new String(buffer)); 

       final String[] lines = fileContent.toString().split("\n"); 

       for(String line : lines) 
       { 
        final String[] columns = line.split(","); 
        final String postcode = columns[0].replace(" ", "").replace("\"", ""); 

        if (columns.length > 3) 
         visitor.location(postcode, "", ""); 
       } 

       visitor.endFile();     
      } 

      entry = input.getNextEntry(); 
     } 

は実際に動作し、より良い方法があるに違いありません。

+1

Jackson CsvMapperは入力ストリームを一度に1行ずつObject []に解析します。一見の価値があるかもしれません。それはスプリット( "、")より速くなり、エスケープも処理されます。 – tom

答えて

6

これがあなたの必要性に合っているかどうかはっきりしていませんが、opencsv(http://opencsv.sourceforge.net)を試してみましたか?その一例が、本当に直感的です:あなたのケースのために

CSVReader reader = new CSVReader(new FileReader("yourfile.csv")); 
String [] nextLine; 
while ((nextLine = reader.readNext()) != null) { 
    // nextLine[] is an array of values from the line 
    System.out.println(nextLine[0] + nextLine[1] + "etc..."); 
} 

、あなたが必要とするすべてはCSVReaderを作成し、それを使用するために、バッファリーダーにZIPファイルのストリームをラップし、読者を渡すことです:

FileInputStream fis = new FileInputStream(file); 
GZIPInputStream gis = new GZIPInputStream(fis); 
InputStreamReader isr = new InputStreamReader(gis); 
BufferedReader br = new BufferedReader(isr); 
CSVReader reader = new CSVReader(br); 
1

便利なreadLine()メソッドを含むBufferedReaderを使用して、ファイルの内容全体をメモリにロードしないでください。

BufferedReader in = new BufferedReader(new InputStreamReader(input), 1024); 
String line=null; 
while((line=br.readLine())!=null) { 
    String[] columns = line.split(","); 
    //rest of your code 
} 
+0

ZipEntryのInputStreamを取得できないため、これはうまくいかないでしょう。 –

+1

あなたの 'input'変数は' ZipInputStream'ですか?そうであれば、 'ZipInputStream'は現在の' ZipEntry'の 'InputStream'であるので、上記のコードは問題ありません。 – samlewis

関連する問題