JavaでCSVファイルを読み込む方法とパースする方法
CSV(Comma Separated Values)ファイルは、データを列ごとに保存し、セパレータ(通常はカンマ "、")で区切った単なるプレーンテキストファイルである。
例
1,US,United States
2,MY,Malaysia
3,AU,Australia
Either
"1","US","United States"
"2","MY","Malaysia"
"3","AU","Australia"
備考
こちらをお読みください RFC4180 CSV(Comma Separated Values)形式についての文書です。
CSVファイルでは、通常、2つの問題があります。
1. セパレータを含むフィールド、例えばセパレータがカンマのフィールド。
"aaa","b,bb","ccc"
2. ダブルクォートを使ってフィールドを囲むと、フィールドにダブルクォートが含まれる。この問題を解決するには、二重引用符をフィールドの内部に表示するには、その前に別の二重引用符 ( RFC4180 )
"aaa","b""bb","ccc"
このチュートリアルでは、CSVファイルから値を読み取り、パースし、印刷するための3つの例を紹介します。
- CSV ファイルを簡単なフォーマットでパースするソリューションです。
- おかしな書式のCSVファイル(区切り文字や二重引用符を含むフィールド)を解析するための高度なソリューション
- サードパーティ製ソリューション、OpenCSVの例です。
1. シンプルな解決策
CSVファイルにセパレータや二重引用符が含まれていないことが確認された場合、単純に標準の
split()
を使用してCSVファイルをパースします。
1.1 簡単なCSVファイルの表示
"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia"
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
"1.0.8.0","1.0.15.255","16779264","16781311","CN","China"
"1.0.16.0","1.0.31.255","16781312","16785407","JP","Japan"
"1.0.32.0","1.0.63.255","16785408","16793599","CN","China"
"1.0.64.0","1.0.127.255","16793600","16809983","JP","Japan"
"1.0.128.0","1.0.255.255","16809984","16842751","TH","Thailand"
1.2には魔法はありません。上のテキストファイルを読み込んで、カンマ区切りで分割するだけです。
package com.mkyong.csv;
import java.io;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io;
public class CSVReader {
public static void main(String[] args) {
String csvFile = "/Users/mkyong/csv/country.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) ! = null) {
// use comma as separator
String[] country = line.split(cvsSplitBy);
System.out.println("Country [code= " + country[4] + " , name=" + country[5] + "]");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br ! = null) { try {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
1.3 JDK 7 以降では try-resources を使用します。
package com.mkyong.csv;
import java.io;
import java.io.FileReader;
import java.io.IOException;
public class CSVReader {
public static void main(String[] args) {
String csvFile = "/Users/mkyong/csv/country.csv";
String line = "";
String cvsSplitBy = ",";
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) ! = null) {
// use comma as separator
String[] country = line.split(cvsSplitBy);
System.out.println("Country [code= " + country[4] + " , name=" + country[5] + "]");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
出力
Country [code= "AU" , name="Australia"]
Country [code= "CN" , name="China"]
Country [code= "AU" , name="Australia"]
Country [code= "CN" , name="China"]
Country [code= "JP" , name="Japan"]
Country [code= "CN" , name="China"]
Country [code= "JP" , name="Japan"]
Country [code= "TH" , name="Thailand"]
2. 事前に解決しておく
このソリューションは、"デリミタまたはダブルクォート"を含むフィールドを解決し、カスタムデリミタとカスタム囲みフィールドもサポートします。以下のCSVパース例とJUnitテストケースで、その動作を確認してください。
<ブロッククオート
備考
同様に、フィールドに二重引用符を表示する必要があり、その前にエスケープのために別の二重引用符を付ける場合、例えば次のようになります。
"aaa","b""bb","ccc"
2.1 別のCSVファイルを表示する
10,AU,Australia
11,AU,Aus""tralia
"12","AU","Australia"
"13","AU","Aus","tralia"
"14","AU","Aus,tralia"
2.2 次の例は、この記事â"からヒントを得たものです。 CSVファイルのクラスだけが必要です "(一部は他の機能をサポートするために修正されているので、"修正コメント"を読んでください)と、このサードパーティの オープンCSV ライブラリです。
package com.mkyong.utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CSVUtils {
private static final char DEFAULT_SEPARATOR = ',';
private static final char DEFAULT_QUOTE = '"';
public static void main(String[] args) throws Exception {
String csvFile = "/Users/mkyong/csv/country2.csv";
Scanner scanner = new Scanner(new File(csvFile));
while (scanner.hasNext()) {
List<String> line = parseLine(scanner.nextLine());
System.out.println("Country [id= " + line.get(0) + ", code= " + line.get(1) + " , name=" + line.get(2) + "]" );
}
scanner.close();
}
public static List<String> parseLine(String cvsLine) {
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
}
public static List<String> parseLine(String cvsLine, char separators) {
return parseLine(cvsLine, separators, DEFAULT_QUOTE);
}
public static List<String> parseLine(String cvsLine, char separators, char customQuote) {
List<String> result = new ArrayList<>();
//if empty, return!
if (cvsLine == null && cvsLine.isEmpty()) {
return result;
}
if (customQuote == ' ') {
customQuote = DEFAULT_QUOTE;
}
if (separators == ' ') {
separators = DEFAULT_SEPARATOR;
}
StringBuffer curVal = new StringBuffer();
boolean inQuotes = false;
boolean startCollectChar = false;
boolean doubleQuotesInColumn = false;
char[] chars = cvsLine.toCharArray();
for (char ch : chars) {
if (inQuotes) {
startCollectChar = true;
if (ch == customQuote) {
inQuotes = false;
doubleQuotesInColumn = false;
} else {
//Fixed : allow "" in custom quote enclosed
if (ch == '\"') {
if (!doubleQuotesInColumn) {
curVal.append(ch);
doubleQuotesInColumn = true;
}
} else {
curVal.append(ch);
}
}
} else {
if (ch == customQuote) {
inQuotes = true;
//Fixed : allow "" in empty quote enclosed
if (chars[0] ! = '"' && customQuote == '\"') {
curVal.append('"');
}
//double quotes in column will hit this!
if (startCollectChar) {
curVal.append('"');
}
} else if (ch == separators) {
result.add(curVal.toString());
curVal = new StringBuffer();
startCollectChar = false;
} else if (ch == '\r') {
//ignore LF characters
continue;
} else if (ch == '\n') {
//the end, break!
break;
} else {
curVal.append(ch);
}
}
}
result.add(curVal.toString());
return result;
}
}
出力
Country [id= 10, code= AU , name=Australia]
Country [id= 11, code= AU , name=Aus"tralia]
Country [id= 12, code= AU , name=Australia]
Country [id= 13, code= AU , name=Aus"tralia]
Country [id= 14, code= AU , name=Aus,tralia]
3.3 次のユニットテストを確認し、quot;カンマと二重引用符の問題をテストしなさい。
package com.mkyong.csv;
import com.mkyong.utils.CSVUtils;
import org.hamcrest.core.IsNull;
import org.junit.Test;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
public class CSVUtilsTest {
@Test
public void test_no_quote() {
String line = "10,AU,Australia";
List<String> result = CSVUtils.parseLine(line);
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Australia"));
}
@Test
public void test_no_quote_but_double_quotes_in_column() throws Exception {
String line = "10,AU,Aus\"\"\"tralia";
List<String> result = CSVUtils.parseLine(line);
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Aus\"tralia"));
}
@Test
public void test_double_quotes() {
String line = "\"10\",\"AU\",\"Australia\"";
List<String> result = CSVUtils.parseLine(line);
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Australia"));
}
@Test
public void test_double_quotes_but_double_quotes_in_column() {
String line = "\"10\",\"AU\",\"Aus\"\"tralia\"";
List<String> result = CSVUtils.parseLine(line);
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Aus\"tralia"));
}
@Test
public void test_double_quotes_but_comma_in_column() {
String line = "\"10\",\"AU\",\"Aus,tralia\"";
List<String> result = CSVUtils.parseLine(line);
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Aus,tralia"));
}
}
3.4 カスタムセパレータとカスタムクロージャフィールドをテストする、別のユニットテストをレビューしてください。
package com.mkyong.csv;
import com.mkyong.utils.CSVUtils;
import org.hamcrest.core.IsNull;
import org.junit.Test;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
public class CSVUtilsTestCustom {
@Test
public void test_custom_separator() {
String line = "10|AU|Australia";
List<String> result = CSVUtils.parseLine(line, '|');
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Australia"));
}
@Test
public void test_custom_separator_and_quote() {
String line = "'10'|'AU'|'Australia'";
List<String> result = CSVUtils.parseLine(line, '|', '\'');
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Australia"));
}
@Test
public void test_custom_separator_and_quote_but_custom_quote_in_column() {
String line = "'10'|'AU'|'Aus|tralia'";
List<String> result = CSVUtils.parseLine(line, '|', '\'');
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Aus|tralia"));
}
@Test
public void test_custom_separator_and_quote_but_double_quotes_in_column() {
String line = "'10'|'AU'|'Aus\"\"\"tralia'";
List<String> result = CSVUtils.parseLine(line, '|', '\'');
assertThat(result, IsNull.notNullValue());
assertThat(result.size(), is(3));
assertThat(result.get(0), is("10"));
assertThat(result.get(1), is("AU"));
assertThat(result.get(2), is("Aus\"tralia"));
}
}
3. OpenCSVの例
上記のシンプルで高度な解決策に満足できない場合は、サードパーティのCSVライブラリを使ってみてください -。 オープンCSV .
3.1 Maven
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>3.8</version>
</dependency>
3.2 CSVファイルを表示する。
10,AU,Australia
11,AU,Aus""tralia
"12","AU","Australia"
"13","AU","Aus","tralia"
"14","AU","Aus,tralia"
3.2 OpenCSVのサンプルを使って、上記のCSVファイルをパースしてください。
package com.mkyong.csv;
import com.opencsv.CSVReader;
import java.io.FileReader;
import java.io.IOException;
public class CSVReaderExample {
public static void main(String[] args) {
String csvFile = "/Users/mkyong/csv/country3.csv";
CSVReader reader = null;
try {
reader = new CSVReader(new FileReader(csvFile));
String[] line;
while ((line = reader.readNext()) ! = null) {
System.out.println("Country [id= " + line[0] + ", code= " + line[1] + " , name=" + line[2] + "]");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
出力量
Country [id= 10, code= AU , name=Australia]
Country [id= 11, code= AU , name=Aus"tralia]
Country [id= 12, code= AU , name=Australia]
Country [id= 13, code= AU , name=Aus"tralia]
Country [id= 14, code= AU , name=Aus,tralia]
備考
その他の例については、こちらをご参照ください。 OpenCSVの公式ドキュメント .
完了
参考
- CSV ファイルにのみ必要なクラス
- CSVHelperの使用例
- Ostermiller Javaユーティリティ - カンマ区切り値(CSV)
- RFC4180 - カンマ区切り値(CSV)形式
- OpenCSVウェブサイト
- Java - データをCSVファイルにエクスポートする方法
Translated from : https://mkyong.com/java/how-to-read-and-parse-csv-file-in-java/
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ハートビート・エフェクトのためのHTML+CSS
-
HTML ホテル フォームによるフィルタリング
-
HTML+cssのボックスモデル例(円、半円など)「border-radius」使いやすい
-
HTMLテーブルのテーブル分割とマージ(colspan, rowspan)
-
ランダム・ネームドロッパーを実装するためのhtmlサンプルコード
-
Html階層型ボックスシャドウ効果サンプルコード
-
QQの一時的なダイアログボックスをポップアップし、友人を追加せずにオンラインで話す効果を達成する方法
-
sublime / vscodeショートカットHTMLコード生成の実装
-
HTMLページを縮小した後にスクロールバーを表示するサンプルコード
-
html のリストボックス、テキストフィールド、ファイルフィールドのコード例