2016-08-23 66 views
0

鑑於我有一個csv文件,如本解析csv文件來填充數據庫

str_name,int_points,int_bonus 
joe,2,5 
Moe,10,15 
Carlos,25,60 

我可以有列的X數和行y個csv文件,所以我試圖建立一個通用的方法解析它並將數據填充到dynamodb表中。

爲了填充dynamodb表我會做這樣的事

String line = ""; 
    String cvsSplitBy = ","; 

    try (BufferedReader br = new BufferedReader(
           new InputStreamReader(objectData, "UTF-8")); 

     while ((line = br.readLine()) != null) { 

      // use comma as separator 
      String[] elements = line.split(cvsSplitBy); 

      try { 
       table.putItem(new Item() 
        .withPrimaryKey("name", elements[0]) 
        .withInt("points", elements[1]) 
        .withInt("bonus", elements[2]) 
        .....); 

       System.out.println("PutItem succeeded: " + elements[0]); 

      } catch (Exception e) { 
       System.err.println("Unable to add user: " + elements); 
       System.err.println(e.getMessage()); 
       break; 
      } 

     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

但是我不會總是知道閹我正在將一個int或字符串,它是在csv文件depenedent所以我很有點不知道如何創建一個通用函數,它會讀取我的csv文件的第一行,並利用前綴來指示特定列是int還是字符串。

+0

你不能指定你的CSV文件的格式嗎? –

+0

我會使用類似opencsv的API。當你解析CSV文件時,你會得到一個String []的String [],這將幫助你在這種情況下。 – lsiva

+0

@dsp_user我的csv文件將完全像我上面發佈的示例..除了課程將有更多的列和行.. – user1010101

回答

0

只需存儲標籤(第一行),然後在迭代行值時,根據標籤決定調用哪種方法。如果您不反對帶來一些外部依賴性,我建議您使用一些外部csv閱讀器,例如 SuperCsv 使用這個庫,你可以讀取每一行作爲一個Map(label-> val),然後遍歷條目並基於標籤前綴更新你的數據庫用正確的方法。或者只是讀取標題,然後將每行讀取爲一個列表。

例子:

這當然是非常粗略的,我可能會重構它以某種方式(如對每一列,而不是醜陋的交換機的處理器列表) ,但它表明你的想法

 List<String> labels = new ArrayList<>();//store first row here 
     List<String> elements = new ArrayList<>();//currently processed line here 
     Item item = new Item(); 
     for (int i = 0; i < elements.size(); i++) { 
      String label = labels.get(i); 
      switch (getTypePrefix(label)){ 
       case "int": 
        item = item.withInt(getName(label),elements.get(i)); 
        break; 
       case "str": 
        item = item.withString(getName(label),elements.get(i)); 
        break; 
       default: 
        //sth 
        break; 
      } 
     } 
     table.putItem(item); 
+0

問題不在於讀取行,而在於讀取行和列之後如何插入數據。 – user1010101

+0

好吧,讓我準備一些簡單的例子,我的意思是 – molok

+0

增加了一個簡單的例子 – molok

0

好的,我不能發表評論,所以我寫了一個簡單的例子。請注意,我不熟悉您使用的是亞馬遜的API,但你應該明白我的意思我怎麼會去了解它(我基本上是重寫代碼)

 String line = ""; 
     String cvsSplitBy = ","; 

     try (BufferedReader br = new BufferedReader(
          new InputStreamReader(objectData, "UTF-8")); 

    String[] colNames = br.readLine().split(cvsSplitBy);  //first line just to get the column names 
    while ((line = br.readLine()) != null) { 
     String currColumnName = colNames.get(i); 
     // use comma as separator 
     String[] elements = line.split(cvsSplitBy); 
     boolean isInt ; 
     for (int i = 0; i < elements.length;i++){ 

     try { 
      try{ 
      int iVal = new Integer(elements[i]); 
      isInt = true; 
      }catch(NumberFormatException e){ 
      //process exception 
      isInt = false; 
      } 
      if(isInt){ 
      table.putItem.(new Item().withInt(currColumnName,iVal)); 
      }else{ 
      table.putItem.(new Item().withString(currColumnName),elements[i])); //don't even know whether there is a withString method 
      } 

      System.out.println("PutItem succeeded: " + elements[i]); 

     } catch (Exception e) { 
      System.err.println("Unable to add user: " + elements); 
      System.err.println(e.getMessage()); 
      break; 
     } 
     } 

    } 

} catch (IOException e) { 
    e.printStackTrace(); 
} 

這個例子假設你的第一個行包含存儲在數據庫中的列名稱。你不必寫任何地方,無論他們是一個int還是一個字符串,因爲有一個檢查程序(當然這不是最有效的方法,你可以寫一些更好的,也許是Molok建議的)