私のcsvはSystem.outに読み込まれていますが、スペースのあるテキストは次の行に移動することに気づきました(リターン\ nとして)
これが私のcsvの始まりです:
first,last,email,address 1, address 2
john,smith,[email protected],123 St. Street,
Jane,Smith,[email protected],4455 Roger Cir,apt 2
アプリを実行した後、スペース(アドレス1)を持つセルは次の行にスローされます。
import Java.io.File;
import Java.io.FileNotFoundException;
import Java.util.Scanner;
public class main {
public static void main(String[] args) {
// -define .csv file in app
String fileNameDefined = "uploadedcsv/employees.csv";
// -File class needed to turn stringName to actual file
File file = new File(fileNameDefined);
try{
// -read from filePooped with Scanner class
Scanner inputStream = new Scanner(file);
// hashNext() loops line-by-line
while(inputStream.hasNext()){
//read single line, put in string
String data = inputStream.next();
System.out.println(data + "***");
}
// after loop, close scanner
inputStream.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
コンソールの結果は次のとおりです。
first、last、email、address 1、address 2 john、smith、blah @ blah.com、123 St。 ストリート、 ジェーン、スミス、blech @ blech.com、4455 ロジャー Cir、apt 2
スキャナーを間違って使用していますか?
scanner.useDelimiter(",");
これは動作するはずです。
import Java.io.File;
import Java.io.FileNotFoundException;
import Java.util.Scanner;
public class TestScanner {
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("/Users/pankaj/abc.csv"));
scanner.useDelimiter(",");
while(scanner.hasNext()){
System.out.print(scanner.next()+"|");
}
scanner.close();
}
}
CSVファイルの場合:
a,b,c d,e
1,2,3 4,5
X,Y,Z A,B
出力は次のとおりです。
a|b|c d|e
1|2|3 4|5
X|Y|Z A|B|
エラーのあるCSVパーサーの書き込みを停止してください!
私は何百ものCSVパーサーを見ており、いわゆるtutorialsと呼ばれています。
それらのほぼすべてが間違っています!
これは私には影響しないので、それほど悪いことではありませんが、CSV readersを書き込もうとして間違った人はCSV writersを書きます。また、それらを間違えます。そして、これらのパーサーを作成する必要があります。
CSV(それほど明白ではない順に):
"foo","","bar"
または"foo",,"bar"
Frodo's Ring
は'Frodo''s Ring'
になります"foo""", """bar", """"
)これが問題ではなく明らかだと思われる場合は、もう一度考え直してください。 every single oneのこれらの項目が誤って実装されているのを見てきました。 majorソフトウェアパッケージでも。 (例:Officeスイート、CRMシステム)
すぐに使える、すぐに使えるCSVリーダーとライターがあります。
自分で書くことに固執する場合は、少なくとも(非常に短い) RFC for CSV を読んでください。
Scanner.next()
は改行を読み取りませんが、空白で区切られた次のトークンを読み取ります(デフォルトでは、useDelimiter()
が区切りパターンの変更に使用されなかった場合)。行を読み取るには、Scanner.nextLine()
を使用します。
単一の行を読んだら、String.split(",")
を使用して行をフィールドに分割できます。これにより、必要な数のフィールドで構成されていない行を識別できます。 useDelimiter(",");
を使用すると、ファイルの行ベースの構造が無視されます(各行は、コンマで区切られたフィールドのリストで構成されます)。例えば:
while (inputStream.hasNextLine())
{
String line = inputStream.nextLine();
String[] fields = line.split(",");
if (fields.length >= 4) // At least one address specified.
{
for (String field: fields) System.out.print(field + "|");
System.out.println();
}
else
{
System.err.println("Invalid record: " + line);
}
}
既に述べたように、CSVライブラリを使用することをお勧めします。たとえば、これ(およびuseDelimiter(",")
ソリューション)は、,
文字を含む引用符付き識別子を正しく処理しません。
既存のCSVライブラリを使用することは、最初からRFC-4180に準拠することをお勧めします。前述のOpenCSVとOster Millerに加えて、他にも一連のCSVライブラリがあります。パフォーマンスに興味がある場合は、 niVocity/csv-parsers-comparison をご覧ください。それはそれを示しています
jDK 6、7、8、または9のいずれかを使用すると、常に最速です。この調査では、これら3つのいずれにもRFC 4180互換性の問題は見つかりませんでした。 OpenCSVとOster Millerの両方が、それらの約2倍遅いことがわかりました。
私は著者とは一切関係ありませんが、uniVocity CSVパーサーに関しては、著者がそのパーサーと同じであるため、研究が偏っている可能性があります。
注目すべきは、SimpleFlatMapperの作成者が パフォーマンス比較 を公開したことです。
NextLine()を区切り文字(?=([^\"]*\"[^\"]*\")*[^\"]*$)")
で分割します。