2010-10-11 18 views
5

Ich habe diese seltsame Situation, wo ich horizontal lesen muss. So bekomme ich eine CSV-Datei, die Daten im Querformat hat. Wie unten:Parsing CSV in Java

CompanyName,RunDate,10/27/2010,11/12/2010,11/27/2010,12/13/2010,12/27/2010.... 

die Termine für alle nach RunDate gezeigt sind Werte für die Laufdatumsfeld und ich muss das Feld aktualisieren, für das Unternehmen in meinem System. Die Datumswerte sind keine Fixnummer, sie können einen einzelnen Wert von 10 bis n haben. Also muss ich all diese Werte lesen und im System aktualisieren. Ich schreibe das in Java.

+0

nicht so seltsam eine Situation, wie Sie vielleicht denken :) –

+0

Bibliotheken wie [OpenCSV] (http://opencsv.sourceforge.net/) behandeln alle seltsamen Fälle für CSV-Dateien (neue Zeilen, Abgrenzung, etc). – Joshua

+0

Obwohl es keine "seltsamen" Fälle gibt, wird die Verwendung einer Bibliothek (1) die Wahrscheinlichkeit von Fehlern beim Parsen verringern; (2) bieten mehr Funktionen; (3) eine ausdehnbare Lösung ergeben; und (4) das Parsen von zukünftigen CSV-Dateien (falls erforderlich) leicht zu integrieren. –

Antwort

4

teilen Sie sie durch "," und analysieren Sie es und verwenden Sie die Liste, um alle diese Werte hinzuzufügen.

Wie andere hat zum Spalten vorgeschlagen und Parsen Sie opencsv

+0

-1 dies wird nicht mit Feldern mit Kommas im Feld, das ist völlig gültig CSV. Das Teilen auf "," funktioniert in einem vereinfachten Fall, aber nur gelegentlich in einem realistischen Fall. –

+0

@Dave DeLong können Sie Ihren Kommentar erarbeiten –

+0

life.java Betrachten Sie diese CSV-Zeile: '" Hallo ", mein Name ist, Dave'. Es hat 5 Felder: 'Hallo,' und 'mein' und' Name' und 'ist' und' Dave'. Dein Vorschlag würde 6 ergeben: 'Hallo', '' ',' mein', 'Name',' ist' und 'Dave' –

1

Sie durch das Lesen Sie die gesamte Zeile in einen String starten können. Dann verwenden Sie die Funktion String.split (...), um alle Token in der Zeile abzurufen, in der das verwendete Trennzeichen "," ist. (oder ist es "\", wenn Sie eine Regex verwenden?)

+0

Sie können einfach 'String.split (", ")' aufrufen. –

+0

Danke, ich werde versuchen, mich daran zu erinnern, ich benutze selten eine Regex. – camickr

1

Um jeden Wert einzeln zu erhalten, verwenden Sie einen StringTokenizer. Konstruieren Sie es mit StringTokenizer(str, ","). (nicht empfohlen)

Verwenden Sie die split()-Methode der String-Klasse, die alle Token in ein Array lädt.

Verwenden Sie die DateFormat Klasse, um jedes Datum zu analysieren - speziell DateFormat.parse(String).

+1

Vom 'StringTokenizer' api: StringTokenizer ist eine Legacy-Klasse, die aus Kompatibilitätsgründen beibehalten wird, obwohl ihre Verwendung in neuem Code nicht empfohlen wird. Es wird empfohlen, dass jeder, der diese Funktionalität sucht, stattdessen die Split-Methode von String oder das Paket java.util.regex verwendet. – Qwerky

+0

: peinlich: Ich sollte wahrscheinlich die Dokumentation nachschlagen, bevor ich eine Antwort empfehle.

+0

@Qwerky - Ich hasse es, dass sie eine vollkommen gute Klasse weggeworfen haben - aber Sie haben Recht. – KevinDTimm

2

Verwenden Sie java.util.Scanner - Sie können useDelimiter() aufrufen, um das Komma als Trennzeichen zu verwenden, und neue Token mit next() lesen. Der Scanner kann direkt aus Ihrer Datei oder einer Zeichenfolge aus der Datei erstellt werden.

2

Eine CSV-Datei ist eine \n beendet Datei, die jede Spalte getrennt werden kann entweder durch:

  • Comma oder
  • Tabs \t

Ich schlage vor, dass Sie einen BufferedReader haben, die liest CSV-Datei und verwenden Sie die readLine() Methode, um die Zeile zu lesen.

Verwenden Sie aus jeder Zeile String.split(arg), wobei arg Ihr Komma oder Tab \t sein wird, um eine Reihe von Spalten zu haben .... von dort wissen Sie, was zu tun ist.

+0

Das 'C' in' CSV' steht für Komma - google für 'TSV' für" Tab-getrennte Werte " –

+0

@Stephen P, aber was hindert jemanden daran, Tabs in eine CSV-Datei zu schreiben? –

1

Bei weitem der nützlichste Seite zum Thema CSV-Parsing ich je gefunden habe, ist folgende:

http://secretgeek.net/csv_trouble.asp

Grundsätzlich erhalten eine etablierte Bibliothek es für Sie zu tun, weil csv-Parsing ist täuschend trickreich.

+0

überhaupt nicht schwierig .... es ist eine einfache Komma oder tabulatorgetrennte Datei. –

+0

@Die Elite - hat den geposteten Artikel nicht gelesen, oder? – KevinDTimm

+0

Ich tat es jetzt .... wenn Marcos es könnte, könnte das jeder ... * sarkastisches Lachen * –

7

String, Split (",") wird wahrscheinlich nicht funktionieren.
Es teilt Felder mit eingebetteten Kommas ("Foo, Inc."), obwohl sie ein einzelnes Feld in der CSV-Zeile sind.

Was passiert, wenn der Firmenname ist:
                Company, Inc.
oder noch schlimmer:
                Joes "Gut, schnell und billig" Essen


Laut Wikipedia:         (http://en.wikipedia.org/wiki/Comma-separated_values)

Felder mit eingebetteten Kommata müssen in doppelten Anführungszeichen eingeschlossen werden.

1997,Ford,E350,"Super, luxurious truck" 

Felder mit eingebetteten doppelten Anführungszeichen müssen in doppelten Anführungszeichen eingeschlossen werden, und jede der eingebetteten doppelte Anführungszeichen muß durch ein Paar doppelter Anführungszeichen dargestellt werden.

1997,Ford,E350,"Super ""luxurious"" truck" 


Schlimmer noch, zitierte Felder Zeilenumbrüche haben (Zeilenumbrüche; "\ n") eingebettet:

Felder mit eingebetteten Zeilenumbrüche müssen in doppelte Anführungszeichen eingeschlossen werden.

1997,Ford,E350,"Go get one now 
    they are going fast" 



dies das Problem mit String zeigt, Split ("") Parsen Komma:

Die CSV-Zeile ist:

a, b, c, "Company, Inc.", d, e, "Joe's" "Gut, schnell und billig" "Food", f, 10/11/2010,1/1/2011, g, h, i


// Test String.split(",") against CSV with 
// embedded commas and embedded double-quotes in 
// quoted text strings: 
// 
// Company names are: 
//  Company, Inc. 
//  Joe's "Good, Fast, and Cheap" Food 
// 
// Which should be formatted in a CSV file as: 
//  "Company, Inc." 
//  "Joe's ""Good, Fast, and Cheap"" Food" 
// 
// 
public class TestSplit { 
    public static void TestSplit(String s, String splitchar) { 
     String[] split_s = s.split(splitchar); 

     for (String seg : split_s) { 
      System.out.println(seg); 
     } 
    } 


    public static void main(String[] args) { 
     String csvLine = "a,b,c,\"Company, Inc.\", d," 
          + " e,\"Joe's \"\"Good, Fast," 
          + " and Cheap\"\" Food\", f," 
          + " 10/11/2010,1/1/2011, h, i"; 

     System.out.println("CSV line is:\n" + csvLine + "\n\n"); 
     TestSplit(csvLine, ","); 
    } 
}


erzeugt die folgende:


D:\projects\TestSplit>javac TestSplit.java 

D:\projects\TestSplit>java TestSplit 
CSV line is: 
a,b,c,"Company, Inc.", d, e,"Joe's ""Good, Fast, and Cheap"" Food", f, 10/11/2010,1/1/2011, g, h, i 


a 
b 
c 
"Company 
Inc." 
d 
e 
"Joe's ""Good 
Fast 
and Cheap"" Food" 
f 
10/11/2010 
1/1/2011 
g 
h 
i 

D:\projects\TestSplit> 



Wo die CSV-Zeile sollte als analysiert werden:


a 
b 
c 
"Company, Inc." 
d 
e 
"Joe's ""Good, Fast, and Cheap"" Food" 
f 
10/11/2010 
1/1/2011 
g 
h 
i 
+0

Nice, um Demo-Code zur Verfügung zu stellen. –

+0

danke! froh, das zu tun! –

0

Sie wirklich univocity-parsers als CSV-Parser kommt mit vielen Funktionen sollten versuchen, alle möglichen Sonderfälle (unescaped Zitate, gemischte Linie Trennzeichen, BOM-kodierte Dateien, usw.), die man auch um die fastest CSV libraries zu behandeln.

Einfaches Beispiel eine Datei zu analysieren:

CsvParserSettings settings = new CsvParserSettings(); //heaps of options here, check the docs 
CsvParser parser = new CsvParser(settings); 

//loads everything into memory, simple but can be slow. 
List<String[]> allRows = parser.parseAll(new File("/path/to/your.csv")); 

//parse iterating over each row 
for(String[] row : parser.iterate(new File("/path/to/your.csv"))){ 
    //process row here 
} 

//and many other possibilities: Java bean processing, column selection, format detection, etc. 

Disclosure: Ich bin der Autor dieser Bibliothek. Es ist Open-Source und kostenlos (Apache V2.0 Lizenz).