# CSV Datei einlesen



## Dit (7. Dez 2005)

Hallo zusammen   ,

Ich soll für einen Autohändler Tabellen in MySql speichern.
habe die Excel Datei bereits in CSV konvertiert.  :wink: 

nun bin ich gerade dabei die CSV einzulesen bzw. zu verarbeiten und da treten schon die ersten Probleme auf   

die CSV Datei enthält 3 Spalten: Artikelnummer;Artikelbezeichnung;Preis in €
wo z.B. die Werte     1;Reifen;75 drin stehen.

nun soll ich die sachen in eine MySQL DB einlesen. Das Problem ist nun, dass ich alles in einem String "Datei" gespeichert habe, aber es am besten wäre die 3 Spalten in die 3 Sachen zu speichern:

int Artikelnummer;
String Artikelbezeichnung;
int Preis;

denn so könnte ich die einzelnen Variablen Problemlos einlesen...
aber wie bekomme ich den String oder die CSV Datei in die 3 Variablen gespeichert??

Ich bedanke mich schon mal für eure Hilfe   :applaus: 

Mein Code sieht zur zeit so aus:


```
try {
    BufferedReader File = new BufferedReader(new FileReader("Test.csv")); 
    String zeile; 
    
    try{ 
    datei = File.readLine(); 
        while (datei != null) 
    { 
    datei = File.readLine(); 
    System.out.println(datei);
    } 
    File.close(); 
    } 
    catch (IOException e) { 
    System.out.println("Fehler beim einlesen der Datei."); 
    } 
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
}
```

aber einen Array möchte ich auch nicht haben, da meine CSV Datei unterschiedlich groß sein kann.


----------



## Mag1c (7. Dez 2005)

Hi,

du liest die Datei zeilenweise ein und splittest den String in die 3 Werte auf. Dabei hilft die z.B. die Methode split aus der Klasse String.

Ich würde aber wahrscheinlich einen anderen Weg gehen. Du könntest aus der CSV-Datei ein SQL-Skript machen, indem du die einzelnen Zeilen in ein INSERT-Statement umwandelst. Ein guter Texteditor sollte dafür ausreichen. Ich würde es wohl mit awk unter Linux machen.
Das wäre natürlich nur dann sinnvoll, wenn es sich um einen einmaligen Vorgang handelt.

Gruß
Mag1c


----------



## Murray (7. Dez 2005)

Aufspalten kann man so einen String z.B. mit einem StringTokenizer, oder aber "mit der Hand am Arm" (mit indexOf und substring). Teilstrings in ints umwandeln: z.B. Integer.parseInt()

Mit der Forensuche sollten sich dazu diverse Threads finden lassen.


----------



## Dit (7. Dez 2005)

also an datei.split(";"); habe ich auch schon gedacht, oder eher gesagt versucht aber das will er auch nicht so recht...

vielleicht ist es auch doch die bessere Methode es über den String oder StreamTokenizer zu machen, aber auch da gibt es einige Probleme...

naja mal weiter versuchen...
aber thx für deine Hilfe


----------



## tini (7. Dez 2005)

Muss das nicht datei.split("[;]") heißen? also [] um das, wo man splitten will?
Dann sollte es doch funktionieren?


----------



## Mag1c (7. Dez 2005)

Hi,



			
				Dit hat gesagt.:
			
		

> also an datei.split(";"); habe ich auch schon gedacht, oder eher gesagt versucht aber das will er auch nicht so recht...



was will denn nicht ?


```
String csv = "efiwefg;iwegfiwgf;wiufewifg";
String[] sp = csv.split(";");
System.out.println("sp.length = "+sp.length);

// Ausgabe: sp.length = 3
```

Gruß
Mag1c


----------



## RicoSoft (7. Dez 2005)

sonst kannst Du generell regex verwenden, um probleme mit den strings zu umgehen, wenn es strings in der form text="freddy;marcel" gibt (und es gibt ja immer sowas, das man eigentlich nicht haben will)


----------



## Dit (7. Dez 2005)

Dann bringt er genau diese meldung:


```
java.lang.Error: Unresolved compilation problem: 
	Unhandled exception type IOException

	at Converter.FileConverter.main(FileConverter.java:26)
Exception in thread "main"
```


----------



## Mag1c (7. Dez 2005)

Hi,

bei Datei-Operationen können IOExceptions auftreten, die du auch irgendwie behandeln mußt. Oben in deinem Code ist das noch drin. Haste das alles gelöscht ?

Gruß
Mag1c


----------



## Dit (7. Dez 2005)

ne die Fehlermeldung war mein Fehler --> Sorry

aber der nutze??? 

denn was soll ich jetzt damit anfangen??


```
sp.length = 1
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
sp.length = 3
```


----------



## Dit (7. Dez 2005)

Ich will doch eigentlich nur die 3 Spalten der CSV Datei in 3 verschiedenen Variablen speichern... :roll: 
ich gebe ja zu man findet ne menge im Internet aber nie das was man sucht...

Denkansatz  :roll: 

ich muss irgendwie eine Schleife schreiben die sofort durchläuft bis die Datein am ende ist...
und in der schleife nur:

den 1 wert in die 1 Variable 
den 2 wert in die 2 Variable
den 3 wert in die 3 Variable 

den 4 wert in die 1 Variable
den 5 wert in die 2 Variable
den 6 wert in die 3 Variable 


usw....

dann wär ich ja zufrieden  :lol:


----------



## bygones (7. Dez 2005)

och gott  der code von magic ist nur bsp wie man split verwendet... 

split liefert dir einen array, in dem die elemente drin sind.


```
String s = "Hallo;1;Was;0.5";
String[] split = s.split(";");
System.out.println(split[0]); // Ausgabe Hallo
System.out.println(split[1]); // Ausgabe 1
System.out.println(split[2]); // Ausgabe Was
System.out.println(split[3]); // Ausgabe 0.5
```


----------



## Dit (7. Dez 2005)

Danke, dann sollte ich das nochmal versuchen.... :roll:


----------



## Dit (7. Dez 2005)

Das ist ja schon mal schön...

in System.out.println(split[0]);  steht mein A_Nummer

ABER:

System.out.println(split[1]);
System.out.println(split[2]);
will er nicht haben...
ich habe auch deine "Methode" versucht die klappt... 

ne was ist das nen müll....  :cry:


----------



## Mag1c (7. Dez 2005)

Hi,

falls du den Debugger nicht benutzen kannst oder willst, helfen meist ein paar einfache Ausgaben bei der Fehlersuche:


```
datei = File.readLine();
System.out.println("Zeile = "+datei);
String[] split = datei.split(";");
System.out.println("Anzahl = "+split.length);
for (int i=0; i < split.length; i++) {
    System.out.println("Element["+i+"] = "+split[i]);
}
```

Gruß
Mag1c


----------



## Dit (7. Dez 2005)

Danke aber ich versuch es gerade erst mal noch über einen aderen weg...


```
try {
		  	String fn = "StreamTokenizerDemo.java";

		    StreamTokenizer st = new StreamTokenizer(new FileReader("Test.csv") );
		    st.slashStarComments( true );
		    st.parseNumbers();
		    st.eolIsSignificant( true );

		    for ( int tval; (tval = st.nextToken()) != StreamTokenizer.TT_EOF; )
		    {
		      if ( tval == StreamTokenizer.TT_NUMBER ){
		      	StreamTokenizer A;
		      	A = st;
		      	System.out.println( "Artikel Nummer: " + A.nval );
		      }
		      else if ( tval == StreamTokenizer.TT_WORD )
		        System.out.println( "Wort: " + st.sval );
		      else if ( tval == StreamTokenizer.TT_EOL )
		        System.out.println( "Ende der Zeile" );

		      else
		        System.out.println( "Zeichen: " + (char) st.ttype );
		    }
```

nach dieser Methode kann ich schon mal String von Int unterscheiden...
die Strings schreibe ich schon mal in meine Variable rein...

dann bleiben noch die 2 Integer (Artikelnummer und Preis)

dann frag ich nach float.... und da Artikelnummer kein float ist müsste das ja eigentlich klappen...


----------



## messi (8. Dez 2005)

Warum benutzt du jetzt Code, der sich deiner CSV-Datei anpasst? Es muss genau anders herum sein! Die Daten müssen deinen Anforderungen genügen.

Du machst das Ganze wie bisher:

10 Du liest eine Zeile ein.
20 Wenn der String null ist, brichst du ab und schließt alle Streams, wie es sich gehört.
30 Dann zerteilst du die Zeile bei jedem Semikolon. Für solche Einmal-Jobs reicht String.split(). Pass aber auf mit Semikolons, die zu einem Wert gehören und die meist escape't sind oder mit in dem quote't String stehen.
40 Jetzt prüfst du, ob du genau drei Werte hast. Wenn nicht, dann gibst du eine Warnung aus und brichst ab oder schreibst diese Zeile in eine andere Datei und führst fort.
50 Da sichergestellt ist, dass an dieser Stelle drei Werte vorhanden sind. Wird der erste und der dritte fest mit Integer.parseInt() bzw. Float.parseFloat() umgewandelt. Wenn auch nur einer nicht klappt, brichst du auch hier ab oder merkst dir diese unsaubere Zeile in einer anderen Datei.
60 Nun hast du für die Zeile einen int, einen String und einen float und schreibst entweder SQL in eine Datei oder direkt in die DB. Wenn du in eine Datei schreibst, dann achte darauf, dass bestimmte Zeichen escape't werden müssen.
70 GOTO 10


----------



## LordSam (8. Dez 2005)

Für das einlesen von CSV Dateien gibt es zahlreiche Bibliotheken, denn es reicht meist nicht aus, einfach nur den String zu 'splitten'. Gerade Excel hat ein spezielles Format um Textfelder zu speichern, so wird Text in Anführungszeichen (") gestellt. Anführungszeichen im Text werden wiederum 'escaped' durch ein doppeltes Anführungszeichen ("")... usw.

Bevor man also loszieht und die Datei selbst verarbeitet, nimmt man doch gleich eine der vielen Bibliotheken.

zum Beispiel: opencsv -> http://opencsv.sourceforge.net/

In deinem Fall wäre das etwa so:

```
CSVReader reader = new CSVReader(new FileReader("yourfile.csv"));
    String[] firstLine = reader.readNext();    // liest die Kopfzeile. Wenn nur Daten drin sind, auskommentieren!!!
    if (firstLine != null) {
        String [] nextLine;
        while ((nextLine = reader.readNext()) != null) {
            // nextLine[] is an array of values from the line
            if (nextLine.length == 3) {     // sind es nicht genau 3 Werte, ist die Zeile 'falsch'
                String nummer = nextLine[0];
                String bezeichnung = nextLine[1];
                float preis = Float.parseFloat(nextLine[2]);    
            } else {
                System.out.println("Zeile konnte nicht richtig gelesen werden...");
            }
        }
    }
```


----------

