CSV檔案的讀取
阿新 • • 發佈:2019-01-06
下午接到專案,讀取一個csv檔案並寫入到資料庫中,把資料存入資料庫中比較簡單,可以參考市面上的寫法,或者用一個物件,存放讀取的資料,批量插入資料庫。
但是下午的資料容量較大,據說有2000W條日處理量,而且要求cpu儘量滿格。
好吧,又是一個坑爹又艱難的專案。言歸正傳,來搞一個csv檔案的讀取。
這裡參考了網上的一些寫法,進行了整合
方法1:
以上為csv的方法處理類下面以 讀取所有內容為例,進行測試package csvtest; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.ArrayList; public class CSVFileUtil { // CSV檔案編碼 public static final String ENCODE = "GBK"; private FileInputStream fis = null; private InputStreamReader isw = null; private BufferedReader br = null; public CSVFileUtil(String filename) throws Exception { fis = new FileInputStream(filename); isw = new InputStreamReader(fis, ENCODE); br = new BufferedReader(isw); } // ==========以下是公開方法============================= /** * 從CSV檔案流中讀取一個CSV行。 * * @throws Exception */ public String readLine() throws Exception { StringBuffer readLine = new StringBuffer(); boolean bReadNext = true; while (bReadNext) { // if (readLine.length() > 0) { readLine.append("\r\n"); } // 一行 String strReadLine = br.readLine(); // readLine is Null if (strReadLine == null) { return null; } readLine.append(strReadLine); // 如果雙引號是奇數的時候繼續讀取。考慮有換行的是情況。 if (countChar(readLine.toString(), '"', 0) % 2 == 1) { bReadNext = true; } else { bReadNext = false; } } return readLine.toString(); } /** *把CSV檔案的一行轉換成字串陣列。指定陣列長度,不夠長度的部分設定為null。 */ public static String[] fromCSVLine(String source, int size) { ArrayList tmpArray = fromCSVLinetoArray(source); if (size < tmpArray.size()) { size = tmpArray.size(); } String[] rtnArray = new String[size]; tmpArray.toArray(rtnArray); return rtnArray; } /** * 把CSV檔案的一行轉換成字串陣列。不指定陣列長度。 */ public static ArrayList fromCSVLinetoArray(String source) { if (source == null || source.length() == 0) { return new ArrayList(); } int currentPosition = 0; int maxPosition = source.length(); int nextComma = 0; ArrayList rtnArray = new ArrayList(); while (currentPosition < maxPosition) { nextComma = nextComma(source, currentPosition); rtnArray.add(nextToken(source, currentPosition, nextComma)); currentPosition = nextComma + 1; if (currentPosition == maxPosition) { rtnArray.add(""); } } return rtnArray; } /** * 把字串型別的陣列轉換成一個CSV行。(輸出CSV檔案的時候用) */ public static String toCSVLine(String[] strArray) { if (strArray == null) { return ""; } StringBuffer cvsLine = new StringBuffer(); for (int idx = 0; idx < strArray.length; idx++) { String item = addQuote(strArray[idx]); cvsLine.append(item); if (strArray.length - 1 != idx) { cvsLine.append(','); } } return cvsLine.toString(); } /** * 字串型別的List轉換成一個CSV行。(輸出CSV檔案的時候用) */ public static String toCSVLine(ArrayList strArrList) { if (strArrList == null) { return ""; } String[] strArray = new String[strArrList.size()]; for (int idx = 0; idx < strArrList.size(); idx++) { strArray[idx] = (String) strArrList.get(idx); } return toCSVLine(strArray); } // ==========以下是內部使用的方法============================= /** *計算指定文字的個數。 * * @param str 文字列 * @param c 文字 * @param start 開始位置 * @return 個數 */ private int countChar(String str, char c, int start) { int i = 0; int index = str.indexOf(c, start); return index == -1 ? i : countChar(str, c, index + 1) + 1; } /** * 查詢下一個逗號的位置。 * * @param source 文字列 * @param st 檢索開始位置 * @return 下一個逗號的位置。 */ private static int nextComma(String source, int st) { int maxPosition = source.length(); boolean inquote = false; while (st < maxPosition) { char ch = source.charAt(st); if (!inquote && ch == ',') { break; } else if ('"' == ch) { inquote = !inquote; } st++; } return st; } /** * 取得下一個字串 */ private static String nextToken(String source, int st, int nextComma) { StringBuffer strb = new StringBuffer(); int next = st; while (next < nextComma) { char ch = source.charAt(next++); if (ch == '"') { if ((st + 1 < next && next < nextComma) && (source.charAt(next) == '"')) { strb.append(ch); next++; } } else { strb.append(ch); } } return strb.toString(); } /** * 在字串的外側加雙引號。如果該字串的內部有雙引號的話,把"轉換成""。 * * @param item 字串 * @return 處理過的字串 */ private static String addQuote(String item) { if (item == null || item.length() == 0) { return "\"\""; } StringBuffer sb = new StringBuffer(); sb.append('"'); for (int idx = 0; idx < item.length(); idx++) { char ch = item.charAt(idx); if ('"' == ch) { sb.append("\"\""); } else { sb.append(ch); } } sb.append('"'); return sb.toString(); } }
public static void main(String []args){ List<stentity> stlist = new ArrayList<stentity>(); try {CSVFileUtil csvutil = new CSVFileUtil("E:\\600600.csv"); String a; while(((a=csvutil.readLine())!=null)){ System.out.println(a); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
可以使用,沒毛病
方法二:
這裡採用的是使用專門的jar包,javacsv.jar,可以上網搜查,具體使用方法貼在下面
package test; import com.csvreader.CsvReader; import com.csvreader.CsvWriter; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class readandwrite { public static void main(String[] args) throws IOException { String [] str = {"省","市","區","街","路","裡","幢","村","室","園","苑","巷","號"}; String inString = ""; String tmpString = ""; File inFile = new File("C://in.csv"); // 讀取的CSV檔案 File outFile = new File("C://outtest.csv");//輸出的CSV文 try { BufferedReader reader = new BufferedReader(new FileReader(inFile)); BufferedWriter writer = new BufferedWriter(new FileWriter(outFile)); CsvReader creader = new CsvReader(reader, ','); CsvWriter cwriter = new CsvWriter(writer,','); while(creader.readRecord()){ inString = creader.getRawRecord();//讀取一行資料 for(int i = 0;i < str.length;i++){ tmpString = inString.replace(str[i], "," + str[i] + ","); inString = tmpString; } //第一個引數表示要寫入的字串陣列,每一個元素佔一個單元格,第二個引數為true時表示寫完資料後自動換行 cwriter.writeRecord(inString.split(","), true); //注意,此時再用cwriter.write(inString)方法寫入資料將會看到只往第一個單元格寫入了資料,“,”沒起到調到下一個單元格的作用 //如果用cwriter.write(String str)方法來寫資料,則要用cwriter.endRecord()方法來實現換行 //cwriter.endRecord();//換行 cwriter.flush();//重新整理資料 } creader.close(); cwriter.close(); } catch (FileNotFoundException ex) { ex.printStackTrace(); } } }
該文章參考了http://lqcjdx.blog.163.com/blog/static/207489241201356111749932/ 以及另一篇文章有啥問題可以評論